#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/major.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/vmalloc.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/time.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <asm-generic/errno-base.h>
#include "../CCP903_SEC_DRIVER/INCLUDE/compate.h"
#include "../CCP903_SEC_DRIVER/INCLUDE/pci_csec.h"
#include "../CCP903_SEC_DRIVER/INCLUDE/desc.h"
#include "../CCP903_SEC_DRIVER/INCLUDE/desc_constr.h"
#include "../CCP903_SEC_DRIVER/INCLUDE/sm2_job.h"
#include "../CCP903_SEC_DRIVER/INCLUDE/rsa_job.h"

#define MAGIC 'Q'
#define IOCTL_TEST_ONE	_IO(MAGIC,23)
#define IOCTL_TEST_TWO	_IO(MAGIC,24)
#define IOCTL_TEST_TRE	_IO(MAGIC,25)

#define CDEVDEMO_MAJOR 255

#define BYTES_PER_MB				1048576
//#define USEC_PER_SEC				1000000
#define BITS_PER_BYTE				8

#define SYM_IV_LEN				0x10
#define SYM_KEY_LEN				0x10
#define SM1_KEY_LEN				0x20

#define ALG_SM1					0x80
#define ALG_SM4					0x90
#define AAI_CBC					0x10

#define ALG_DEC					0x0
#define ALG_ENC					0x1
#define INIT_FIN				0x3

#define SYM_ALG					0

#define USER_MEM				0

#define ONE_MB_DLEN				0x100000
#define OP5_KB_DLEN				0x100000

#define THREADS_NUM				64
#define LOOP_NUM				10

#define SYM_TEST_CNT				1

#define MULTI_THREAD_TEST			1
#define SINGLE_THREAD_TEST			0

#define	TEST_ASYM_SM2				1
#define	TEST_ASYM_RSA				1

static int cdevdemo_major = CDEVDEMO_MAJOR;

struct cdevdemo_dev
{
	struct cdev cdev;
	struct pci_dev *pdev;
	struct semaphore pcie_sem;
	struct mutex mutex;
	unsigned char *pbuf;
	dma_addr_t phy_addr;
	int pkbufsize;
};
struct cdevdemo_dev *cdevdemo_devp;
struct class *cdevdemo_class;


extern void get_random_bytes(void *buf, int nbytes);
extern void inline_cnstr_jobdesc_sm2_genkey(unsigned int *desc, struct sm2_genkey_private_dma *para);
extern void inline_cnstr_jobdesc_sm2_encrypt(unsigned int *desc, struct sm2_enc_private_dma *para);
extern void inline_cnstr_jobdesc_sm2_decrypt(unsigned int *desc, struct sm2_dec_private_dma *para);
extern void inline_cnstr_jobdesc_sm2_signature(unsigned int *desc, struct sm2_sig_private_dma *para);
extern void inline_cnstr_jobdesc_sm2_verify(unsigned int *desc, struct sm2_ver_private_dma *para);
extern void inline_cnstr_jobdesc_sm2_exchange(unsigned int *desc, struct sm2_exc_private_dma *para);
extern void inline_cnstr_jobdesc_rsa_genkey_simplified(unsigned int *desc, struct rsa_genkey_dma *para);
extern void inline_cnstr_jobdesc_rsa_pub_priv_simplified(unsigned int *desc, struct rsa_pub_priv_dma *para);
extern void inline_cnstr_jobdesc_rsa_priv_crt_simplified(unsigned int *desc, struct rsa_pub_priv_dma *para);
struct completion sym_comp[THREADS_NUM];

#if 1
struct sym_thread_st
{
	unsigned char *iv;
	unsigned char *key;
	unsigned int data_len;
	unsigned char *input_data;
	unsigned char *output_data;
};
#endif


int cdevdemo_open(struct inode *inode, struct file *filp)
{
	int ret = 0;

	printk(KERN_NOTICE "======== cdevdemo_open \n");

	//ret = pcie_init();

	return ret;
}

int cdevdemo_release(struct inode *inode, struct file *filp)
{
	int ret = 0;

	printk(KERN_NOTICE "======== cdevdemo_release\n");

	//ret = pci_ccore_del_callback_func(cdevdemo_devp->pdev);
	if(ret)
		printk(KERN_NOTICE "pci_ccore_del_callback_func fail\n");

	//ret = pci_ccore_release(cdevdemo_devp->pdev);
	if(ret)
		printk(KERN_NOTICE "pci_ccore_release fail\n");

	return ret;
}

static long cdevdemo_ioctl(struct file *filp, unsigned int command,
		unsigned long arg)
{
	int ret = 0;

	return ret;
}

static const struct file_operations cdevdemo_fops =
{
	.unlocked_ioctl = cdevdemo_ioctl,
	.owner = THIS_MODULE,
	.open = cdevdemo_open,
	.release = cdevdemo_release,
};


static unsigned char fixed_E_param[3] =
{
		0x01, 0x00, 0x01
};

static unsigned int key1_r2[128] = {
			0xFFFFFFFF,0xFFFFFFFF,0x55523C7F,0xC4523F90,
	        0xEFA00DF3,0x774A259F,0x2E62B4C5,0xD99CB5AD,
	        0xB300A028,0x5E530193,0x0E0C70FB,0x6876939C,
	        0xE616CE62,0x4A11E008,0x6D341EBC,0xACA0A1f5,
			0xFFFFFFFF,0xFFFFFFFF,0x55523C7F,0xC4523F90,
	        0xEFA00DF3,0x774A259F,0x2E62B4C5,0xD99CB5AD,
	        0xB300A028,0x5E530193,0x0E0C70FB,0x6876939C,
	        0xE616CE62,0x4A11E008,0x6D341EBC,0xACA0A1f5,
	        	0xFFFFFFFF,0xFFFFFFFF,0x55523C7F,0xC4523F90,
	        0xEFA00DF3,0x774A259F,0x2E62B4C5,0xD99CB5AD,
	        0xB300A028,0x5E530193,0x0E0C70FB,0x6876939C,
	        0xE616CE62,0x4A11E008,0x6D341EBC,0xACA0A1f5,
			0xFFFFFFFF,0xFFFFFFFF,0x55523C7F,0xC4523F90,
	        0xEFA00DF3,0x774A259F,0x2E62B4C5,0xD99CB5AD,
	        0xB300A028,0x5E530193,0x0E0C70FB,0x6876939C,
	        0xE616CE62,0x4A11E008,0x6D341EBC,0xACA0A1f5,
	        	0xFFFFFFFF,0xFFFFFFFF,0x55523C7F,0xC4523F90,
	        0xEFA00DF3,0x774A259F,0x2E62B4C5,0xD99CB5AD,
	        0xB300A028,0x5E530193,0x0E0C70FB,0x6876939C,
	        0xE616CE62,0x4A11E008,0x6D341EBC,0xACA0A1f5,
			0xFFFFFFFF,0xFFFFFFFF,0x55523C7F,0xC4523F90,
	        0xEFA00DF3,0x774A259F,0x2E62B4C5,0xD99CB5AD,
	        0xB300A028,0x5E530193,0x0E0C70FB,0x6876939C,
	        0xE616CE62,0x4A11E008,0x6D341EBC,0xACA0A1f5,
	        	0xFFFFFFFF,0xFFFFFFFF,0x55523C7F,0xC4523F90,
	        0xEFA00DF3,0x774A259F,0x2E62B4C5,0xD99CB5AD,
	        0xB300A028,0x5E530193,0x0E0C70FB,0x6876939C,
	        0xE616CE62,0x4A11E008,0x6D341EBC,0xACA0A1f5,
			0xFFFFFFFF,0xFFFFFFFF,0x55523C7F,0xC4523F90,
	        0xEFA00DF3,0x774A259F,0x2E62B4C5,0xD99CB5AD,
	        0xB300A028,0x5E530193,0x0E0C70FB,0x6876939C,
	        0xE616CE62,0x4A11E008,0x6D341EBC,0xACA0A1f5
};


static unsigned char sm2_fp_param1[224] =
{
		0x85, 0x42, 0xD6, 0x9E, 0x4C, 0x04, 0x4F, 0x18, 0xE8, 0xB9, 0x24, 0x35,
		0xBF, 0x6F, 0xF7, 0xDE, 0x45, 0x72, 0x83, 0x91, 0x5C, 0x45, 0x51, 0x7D,
		0x72, 0x2E, 0xDB, 0x8B, 0x08, 0xF1, 0xDF, 0xC3,

		0x78, 0x79, 0x68, 0xB4, 0xFA, 0x32, 0xC3, 0xFD, 0x24, 0x17, 0x84, 0x2E,
		0x73, 0xBB, 0xFE, 0xFF, 0x2F, 0x3C, 0x84, 0x8B, 0x68, 0x31, 0xD7, 0xE0,
		0xEC, 0x65, 0x22, 0x8B, 0x39, 0x37, 0xE4, 0x98,

		0x63, 0xE4, 0xC6, 0xD3, 0xB2, 0x3B, 0x0C, 0x84, 0x9C, 0xF8, 0x42, 0x41,
		0x48, 0x4B, 0xFE, 0x48, 0xF6, 0x1D, 0x59, 0xA5, 0xB1, 0x6B, 0xA0, 0x6E,
		0x6E, 0x12, 0xD1, 0xDA, 0x27, 0xC5, 0x24, 0x9A,

		0x42, 0x1D, 0xEB, 0xD6, 0x1B, 0x62, 0xEA, 0xB6, 0x74, 0x64, 0x34, 0xEB,
		0xC3, 0xCC, 0x31, 0x5E, 0x32, 0x22, 0x0B, 0x3B, 0xAD, 0xD5, 0x0B, 0xDC,
		0x4C, 0x4E, 0x6C, 0x14, 0x7F, 0xED, 0xD4, 0x3D,

		0x06, 0x80, 0x51, 0x2B, 0xCB, 0xB4, 0x2C, 0x07, 0xD4, 0x73, 0x49, 0xD2,
		0x15, 0x3B, 0x70, 0xC4, 0xE5, 0xD7, 0xFD, 0xFC, 0xBF, 0xA3, 0x6E, 0xA1,
		0xA8, 0x58, 0x41, 0xB9, 0xE4, 0x6E, 0x09, 0xA2,

		0x85, 0x42, 0xD6, 0x9E, 0x4C, 0x04, 0x4F, 0x18, 0xE8, 0xB9, 0x24, 0x35,
		0xBF, 0x6F, 0xF7, 0xDD, 0x29, 0x77, 0x20, 0x63, 0x04, 0x85, 0x62, 0x8D,
		0x5A, 0xE7, 0x4E, 0xE7, 0xC3, 0x2E, 0x79, 0xB7,

		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
};

extern struct csec_priv_t* cards_enqueue_pre(struct ccore_cards_t *ccore_cards);
extern int cards_enqueue(struct csec_priv_t *csec_priv,uint32_t *desc_addr,dma_addr_t desc_phy_addr,
	       void (*callback)(struct csec_priv_t *csec_priv_s,void *desc_addr_s,dma_addr_t desc_phy_addr_s,uint32_t status_s, void *arg_s),void *arg);
extern struct ccore_cards_t *get_ccore_cards(void);
void ioctl_desc_done(struct csec_priv_t *csec_priv,void *dma_virt,dma_addr_t desc,uint32_t status, void *arg)
{
	struct result *op;
	//csec_debug(KERN_INFO "b\n");
	op = arg;
	op->rst = status;
	if(op->sg_virt)
	{
		dma_unmap_single(csec_priv->dev,op->sg_phy,SGMAX*16,DMA_TO_DEVICE);
		kfree(op->sg_virt);
	}

	atomic_set(&op->op_done,1);
}

void do_sm2_genkey(struct csec_priv_t *csec_priv, unsigned int *desc, dma_addr_t desc_dma, struct sm2_genkey_private_dma *para, struct result *done_op)
{
	int status;

	inline_cnstr_jobdesc_sm2_genkey(desc, para);

	do
	{
		status = cards_enqueue(csec_priv,  desc, desc_dma,ioctl_desc_done,done_op);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);

				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);

	while(atomic_read(&done_op->op_done)!=1)
	{
		if(CDEV_INVL)
		{
			wait_event_timeout(csec_priv->ccore_cards->dq_done,atomic_read(&done_op->op_done),CDEV_INVL);
		}
		//csec_debug(KERN_INFO "a\n");
	}
}

void do_sm2_encrypt(struct csec_priv_t *csec_priv, unsigned int *desc, dma_addr_t desc_dma, struct sm2_enc_private_dma *para, struct result *done_op)
{
	int status;

	inline_cnstr_jobdesc_sm2_encrypt(desc, para);

	do
	{
		status = cards_enqueue(csec_priv,  desc, desc_dma,ioctl_desc_done,done_op);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);

				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);

	while(atomic_read(&done_op->op_done)!=1)
	{
		if(CDEV_INVL)
		{
			wait_event_timeout(csec_priv->ccore_cards->dq_done,atomic_read(&done_op->op_done),CDEV_INVL);
		}
		//csec_debug(KERN_INFO "a\n");
	}
}

void do_sm2_decrypt(struct csec_priv_t *csec_priv, unsigned int *desc, dma_addr_t desc_dma, struct sm2_dec_private_dma *para, struct result *done_op)
{
	int status;

	inline_cnstr_jobdesc_sm2_decrypt(desc, para);

	do
	{
		status = cards_enqueue(csec_priv,  desc, desc_dma,ioctl_desc_done,done_op);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);

				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);

	while(atomic_read(&done_op->op_done)!=1)
	{
		if(CDEV_INVL)
		{
			wait_event_timeout(csec_priv->ccore_cards->dq_done,atomic_read(&done_op->op_done),CDEV_INVL);
		}
		//csec_debug(KERN_INFO "a\n");
	}
}

void do_sm2_signature(struct csec_priv_t *csec_priv, unsigned int *desc, dma_addr_t desc_dma, struct sm2_sig_private_dma *para, struct result *done_op)
{
	int status;

	inline_cnstr_jobdesc_sm2_signature(desc, para);

	do
	{
		status = cards_enqueue(csec_priv,  desc, desc_dma,ioctl_desc_done,done_op);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);

				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);

	while(atomic_read(&done_op->op_done)!=1)
	{
		if(CDEV_INVL)
		{
			wait_event_timeout(csec_priv->ccore_cards->dq_done,atomic_read(&done_op->op_done),CDEV_INVL);
		}
		//csec_debug(KERN_INFO "a\n");
	}
}

void do_sm2_verify(struct csec_priv_t *csec_priv, unsigned int *desc, dma_addr_t desc_dma, struct sm2_ver_private_dma *para, struct result *done_op)
{
	int status;

	inline_cnstr_jobdesc_sm2_verify(desc, para);

	do
	{
		status = cards_enqueue(csec_priv,  desc, desc_dma,ioctl_desc_done,done_op);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);

				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);

	while(atomic_read(&done_op->op_done)!=1)
	{
		if(CDEV_INVL)
		{
			wait_event_timeout(csec_priv->ccore_cards->dq_done,atomic_read(&done_op->op_done),CDEV_INVL);
		}
		//csec_debug(KERN_INFO "a\n");
	}
}

void do_sm2_exchange(struct csec_priv_t *csec_priv, unsigned int *desc, dma_addr_t desc_dma, struct sm2_exc_private_dma *para, struct result *done_op)
{
	int status;

	inline_cnstr_jobdesc_sm2_exchange(desc, para);

	do
	{
		status = cards_enqueue(csec_priv,  desc, desc_dma,ioctl_desc_done,done_op);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);

				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);

	while(atomic_read(&done_op->op_done)!=1)
	{
		if(CDEV_INVL)
		{
			wait_event_timeout(csec_priv->ccore_cards->dq_done,atomic_read(&done_op->op_done),CDEV_INVL);
		}
		//csec_debug(KERN_INFO "a\n");
	}
}

int sm2_genkey_thread(void *para)
{
	struct sm2_genkey_private_dma st_genkey;

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);
	struct result *done_op;

	unsigned char s_pria[32] = {
		0x6F, 0xCB, 0xA2, 0xEF, 0x9A, 0xE0, 0xAB, 0x90, 0x2B, 0xC3, 0xBD, 0xE3, 0xFF, 0x91, 0x5D, 0x44,
		0xBA, 0x4C, 0xC7, 0x8F, 0x88, 0xE2, 0xF8, 0xE7, 0xF8, 0x99, 0x6D, 0x3B, 0x8C, 0xCE, 0xED, 0xEE
	};
	unsigned char s_puba[64] = {
		0x30, 0x99, 0x09, 0x3B, 0xF3, 0xC1, 0x37, 0xD8, 0xFC, 0xBB, 0xCD, 0xF4, 0xA2, 0xAE, 0x50, 0xF3,
		0xB0, 0xF2, 0x16, 0xC3, 0x12, 0x2D, 0x79, 0x42, 0x5F, 0xE0, 0x3A, 0x45, 0xDB, 0xFE, 0x16, 0x55,
		0x3D, 0xF7, 0x9E, 0x8D, 0xAC, 0x1C, 0xF0, 0xEC, 0xBA, 0xA2, 0xF2, 0xB4, 0x9D, 0x51, 0xA4, 0xB3,
		0x87, 0xF2, 0xEF, 0xAF, 0x48, 0x23, 0x39, 0x08, 0x6A, 0x27, 0xA8, 0xE0, 0x5B, 0xAE, 0xD9, 0x8B
	};

	unsigned char *fp256_param, *pub_key, *pri_key;
	unsigned int *desc;
	dma_addr_t fp256_param_dma, desc_dma, pub_key_dma, pri_key_dma;

	fp256_param = dma_alloc_coherent(csec_priv->dev, 224, &fp256_param_dma, GFP_KERNEL | GFP_DMA);
	pub_key = dma_alloc_coherent(csec_priv->dev, 32*2, &pub_key_dma, GFP_KERNEL | GFP_DMA);
	pri_key = dma_alloc_coherent(csec_priv->dev, 32, &pri_key_dma, GFP_KERNEL | GFP_DMA);
	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, &desc_dma, GFP_KERNEL | GFP_DMA);
	if(!pri_key)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	done_op = kzalloc(sizeof(struct result),GFP_KERNEL);
	if(!done_op)
	{
		csec_error(KERN_INFO "done_op kzalloc error\n");
		return -EINVAL;
	}
	memcpy(fp256_param, sm2_fp_param1, 224);
	memcpy(pri_key, s_pria, 32);

	//generate key pair
	st_genkey.ecc_dma.p = fp256_param_dma;
	st_genkey.ecc_dma.a = fp256_param_dma+32;
	st_genkey.ecc_dma.b = fp256_param_dma+32*2;
	st_genkey.ecc_dma.gx = fp256_param_dma+32*3;
	st_genkey.ecc_dma.gy = fp256_param_dma+32*4;
	st_genkey.ecc_dma.n = fp256_param_dma+32*5;
	st_genkey.pubkey_dma.x = pub_key_dma;
	st_genkey.pubkey_dma.y = pub_key_dma+32;
	st_genkey.prikey_dma = pri_key_dma;
	st_genkey.plen = 32;
	st_genkey.nlen = 32;
	st_genkey.ecc_mode = FP;
	st_genkey.rng_mode = CONSTANT;

	do_sm2_genkey(csec_priv, desc, desc_dma, &st_genkey, done_op);
	if(memcmp(s_puba, pub_key, 64))
		printk(KERN_INFO "sm2 generate key failed!\n");

	dma_free_coherent(csec_priv->dev, 224, fp256_param, fp256_param_dma);
	dma_free_coherent(csec_priv->dev, 32*2, pub_key, pub_key_dma);
	dma_free_coherent(csec_priv->dev, 32, pri_key, pri_key_dma);
	dma_free_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, desc, desc_dma);
	kfree(done_op);

	complete(this);
	return 0;
}

int sm2_encrypt_thread(void *para)
{
	struct sm2_enc_private_dma st_enc;

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);
	struct result *done_op;

	unsigned char standard_mes[19] =
	{
		0x65, 0x6E, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73,
		0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64
	};
	unsigned char s_puba[64] = {
		0x43, 0x5B, 0x39, 0xCC, 0xA8, 0xF3, 0xB5, 0x08, 0xC1, 0x48, 0x8A, 0xFC, 0x67, 0xBE, 0x49, 0x1A,
		0x0F, 0x7B, 0xA0, 0x7E, 0x58, 0x1A, 0x0E, 0x48, 0x49, 0xA5, 0xCF, 0x70, 0x62, 0x8A, 0x7E, 0x0A,
		0x75, 0xDD, 0xBA, 0x78, 0xF1, 0x5F, 0xEE, 0xCB, 0x4C, 0x78, 0x95, 0xE2, 0xC1, 0xCD, 0xF5, 0xFE,
		0x01, 0xDE, 0xBB, 0x2C, 0xDB, 0xAD, 0xF4, 0x53, 0x99, 0xCC, 0xF7, 0x7B, 0xBA, 0x07, 0x6A, 0x42
	};
	unsigned char rng_k[32] = {
		0x4C, 0x62, 0xEE, 0xFD, 0x6E, 0xCF, 0xC2, 0xB9, 0x5B, 0x92, 0xFD, 0x6C, 0x3D, 0x95, 0x75, 0x14,
		0x8A, 0xFA, 0x17, 0x42, 0x55, 0x46, 0xD4, 0x90, 0x18, 0xE5, 0x38, 0x8D, 0x49, 0xDD, 0x7B, 0x4F
	};
	unsigned char cipher_text[116] = {
		0x04, 0x24, 0x5C, 0x26, 0xFB, 0x68, 0xB1, 0xDD, 0xDD, 0xB1, 0x2C, 0x4B, 0x6B, 0xF9, 0xF2, 0xB6,
		0xD5, 0xFE, 0x60, 0xA3, 0x83, 0xB0, 0xD1, 0x8D, 0x1C, 0x41, 0x44, 0xAB, 0xF1, 0x7F, 0x62, 0x52,
		0xE7, 0x76, 0xCB, 0x92, 0x64, 0xC2, 0xA7, 0xE8, 0x8E, 0x52, 0xB1, 0x99, 0x03, 0xFD, 0xC4, 0x73, 0x78, 0xF6, 0x05, 0xE3, 0x68, 0x11, 0xF5, 0xC0, 0x74, 0x23, 0xA2, 0x4B, 0x84, 0x40, 0x0F, 0x01,
		0xB8, 0x65, 0x00, 0x53, 0xA8, 0x9B, 0x41, 0xC4, 0x18, 0xB0, 0xC3, 0xAA, 0xD0, 0x0D, 0x88, 0x6C, 0x00, 0x28, 0x64, 0x67, 0x9C, 0x3D, 0x73, 0x60, 0xC3, 0x01, 0x56, 0xFA, 0xB7, 0xC8, 0x0A, 0x02,
		0x76, 0x71, 0x2D, 0xA9, 0xD8, 0x09, 0x4A, 0x63, 0x4B, 0x76, 0x6D, 0x3A, 0x28, 0x5E, 0x07, 0x48, 0x06, 0x53, 0x42, 0x6D
	};

	unsigned char *fp256_param, *pub_key, *msg, *c, *hashin, *hashout, *k;
	unsigned int *desc, *ct;
	dma_addr_t fp256_param_dma, desc_dma, pub_key_dma, msg_dma, c_dma, hashin_dma, ct_dma, k_dma;

	fp256_param = dma_alloc_coherent(csec_priv->dev, 224, &fp256_param_dma, GFP_KERNEL | GFP_DMA);
	pub_key = dma_alloc_coherent(csec_priv->dev, 32*2, &pub_key_dma, GFP_KERNEL | GFP_DMA);
	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, &desc_dma, GFP_KERNEL | GFP_DMA);
	msg = dma_alloc_coherent(csec_priv->dev, 19, &msg_dma, GFP_KERNEL | GFP_DMA);
	c = dma_alloc_coherent(csec_priv->dev, 1+32*2+19+32, &c_dma, GFP_KERNEL | GFP_DMA);
	hashin = dma_alloc_coherent(csec_priv->dev, 32*2+4, &hashin_dma, GFP_KERNEL | GFP_DMA);
	k = dma_alloc_coherent(csec_priv->dev, 32, &k_dma, GFP_KERNEL | GFP_DMA);
	ct= dma_alloc_coherent(csec_priv->dev, 32, &ct_dma, GFP_KERNEL | GFP_DMA);

	if(!ct)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	done_op = kzalloc(sizeof(struct result),GFP_KERNEL);
	if(!done_op)
	{
		csec_error(KERN_INFO "done_op kzalloc error\n");
		return -EINVAL;
	}
	memcpy(fp256_param, sm2_fp_param1, 224);
	memcpy(pub_key, s_puba, 64);
	memcpy(msg, standard_mes, 19);
	memcpy(k, rng_k, 32);

	//encrypt
	st_enc.klen = 19;
	*ct = st_enc.ct = (st_enc.klen + 31)/32;
	st_enc.ecc_dma.p = fp256_param_dma;
	st_enc.ecc_dma.a = fp256_param_dma+32;
	st_enc.ecc_dma.b = fp256_param_dma+32*2;
	st_enc.ecc_dma.gx = fp256_param_dma+32*3;
	st_enc.ecc_dma.gy = fp256_param_dma+32*4;
	st_enc.ecc_dma.n = fp256_param_dma+32*5;
	st_enc.pubkey_dma.x = pub_key_dma;
	st_enc.pubkey_dma.y = pub_key_dma+32;
	st_enc.ciphertext_dma.c1 = c_dma;
	st_enc.ciphertext_dma.c2 = c_dma+1+2*32;
	st_enc.ciphertext_dma.c3 = c_dma+1+2*32+19;
	st_enc.msg_dma = msg_dma;
	st_enc.hashin_dma = hashin_dma;
//	st_enc.hashout_dma = hashout_dma;
	st_enc.ct_dma = ct_dma;
	st_enc.k_dma = k_dma;
	st_enc.plen = 32;
	st_enc.nlen = 32;
	st_enc.ecc_mode = FP;
	st_enc.endian_mode = LITTLE;
	st_enc.rng_mode = CONSTANT;

	do_sm2_encrypt(csec_priv, desc, desc_dma, &st_enc, done_op);
	if(memcmp(c+1, cipher_text+1, 115))
		printk(KERN_INFO "sm2 encrypt failed!\n");

	dma_free_coherent(csec_priv->dev, 224, fp256_param, fp256_param_dma);
	dma_free_coherent(csec_priv->dev, 32*2, pub_key, pub_key_dma);
	dma_free_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, desc, desc_dma);
	dma_free_coherent(csec_priv->dev, 19, msg, msg_dma);
	dma_free_coherent(csec_priv->dev, 1+32*2+19+32, c, c_dma);
	dma_free_coherent(csec_priv->dev, 32*2+4, hashin, hashin_dma);
	dma_free_coherent(csec_priv->dev, 32, k, k_dma);
	dma_free_coherent(csec_priv->dev, 32, ct, ct_dma);
	kfree(done_op);

	complete(this);
	return 0;
}

int sm2_decrypt_thread(void *para)
{
	struct sm2_dec_private_dma st_dec;

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);
	struct result *done_op;

	unsigned char standard_mes[19] =
	{
		0x65, 0x6E, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x73,
		0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64
	};
	unsigned char s_pria[32] = {
		0x16, 0x49, 0xAB, 0x77, 0xA0, 0x06, 0x37, 0xBD, 0x5E, 0x2E, 0xFE, 0x28, 0x3F, 0xBF, 0x35, 0x35,
		0x34, 0xAA, 0x7F, 0x7C, 0xB8, 0x94, 0x63, 0xF2, 0x08, 0xDD, 0xBC, 0x29, 0x20, 0xBB, 0x0D, 0xA0
	};
	unsigned char cipher_text[116] = {
		0x04, 0x24, 0x5C, 0x26, 0xFB, 0x68, 0xB1, 0xDD, 0xDD, 0xB1, 0x2C, 0x4B, 0x6B, 0xF9, 0xF2, 0xB6,
		0xD5, 0xFE, 0x60, 0xA3, 0x83, 0xB0, 0xD1, 0x8D, 0x1C, 0x41, 0x44, 0xAB, 0xF1, 0x7F, 0x62, 0x52,
		0xE7, 0x76, 0xCB, 0x92, 0x64, 0xC2, 0xA7, 0xE8, 0x8E, 0x52, 0xB1, 0x99, 0x03, 0xFD, 0xC4, 0x73, 0x78, 0xF6, 0x05, 0xE3, 0x68, 0x11, 0xF5, 0xC0, 0x74, 0x23, 0xA2, 0x4B, 0x84, 0x40, 0x0F, 0x01,
		0xB8, 0x65, 0x00, 0x53, 0xA8, 0x9B, 0x41, 0xC4, 0x18, 0xB0, 0xC3, 0xAA, 0xD0, 0x0D, 0x88, 0x6C, 0x00, 0x28, 0x64, 0x67, 0x9C, 0x3D, 0x73, 0x60, 0xC3, 0x01, 0x56, 0xFA, 0xB7, 0xC8, 0x0A, 0x02,
		0x76, 0x71, 0x2D, 0xA9, 0xD8, 0x09, 0x4A, 0x63, 0x4B, 0x76, 0x6D, 0x3A, 0x28, 0x5E, 0x07, 0x48, 0x06, 0x53, 0x42, 0x6D
	};

	unsigned char *fp256_param, *pri_key, *msg, *c, *hashin, *hashout;
	unsigned int *desc, *ct;
	dma_addr_t fp256_param_dma, desc_dma, pri_key_dma, msg_dma, c_dma, hashin_dma, ct_dma;

	fp256_param = dma_alloc_coherent(csec_priv->dev, 224, &fp256_param_dma, GFP_KERNEL | GFP_DMA);
	pri_key = dma_alloc_coherent(csec_priv->dev, 32, &pri_key_dma, GFP_KERNEL | GFP_DMA);
	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, &desc_dma, GFP_KERNEL | GFP_DMA);
	msg = dma_alloc_coherent(csec_priv->dev, 19, &msg_dma, GFP_KERNEL | GFP_DMA);
	c = dma_alloc_coherent(csec_priv->dev, 1+32*2+19+32, &c_dma, GFP_KERNEL | GFP_DMA);
	hashin = dma_alloc_coherent(csec_priv->dev, 32*2+4, &hashin_dma, GFP_KERNEL | GFP_DMA);
	ct= dma_alloc_coherent(csec_priv->dev, 32, &ct_dma, GFP_KERNEL | GFP_DMA);

	if(!ct)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	done_op = kzalloc(sizeof(struct result),GFP_KERNEL);
	if(!done_op)
	{
		csec_error(KERN_INFO "done_op kzalloc error\n");
		return -EINVAL;
	}
	memcpy(fp256_param, sm2_fp_param1, 224);
	memcpy(pri_key, s_pria, 32);
	memcpy(c, cipher_text, 116);
	*ct = 1;

	//decrypt
	st_dec.ecc_dma.p = fp256_param_dma;
	st_dec.ecc_dma.a = fp256_param_dma+32;
	st_dec.ecc_dma.b = fp256_param_dma+32*2;
	st_dec.ecc_dma.gx = fp256_param_dma+32*3;
	st_dec.ecc_dma.gy = fp256_param_dma+32*4;
	st_dec.ecc_dma.n = fp256_param_dma+32*5;
	st_dec.ciphertext_dma.c1 = c_dma;
	st_dec.ciphertext_dma.c2 = c_dma+1+2*32;
	st_dec.ciphertext_dma.c3 = c_dma+1+2*32+19;
	st_dec.prikey_dma = pri_key_dma;
	st_dec.msg_dma = msg_dma;
	st_dec.hashin_dma = hashin_dma;
//	st_dec.hashout_dma = hashout_dma;
	st_dec.ct_dma = ct_dma;
	st_dec.plen = 32;
	st_dec.nlen = 32;
	st_dec.klen = 19;
	st_dec.ct = 1;
	st_dec.ecc_mode = FP;
	st_dec.endian_mode = LITTLE;

	memset(done_op,0,sizeof(struct result));
	do_sm2_decrypt(csec_priv, desc, desc_dma, &st_dec, done_op);
	if(memcmp(standard_mes, msg, 19))
		printk(KERN_INFO "sm2 decrypt failed!\n");

	dma_free_coherent(csec_priv->dev, 224, fp256_param, fp256_param_dma);
	dma_free_coherent(csec_priv->dev, 32, pri_key, pri_key_dma);
	dma_free_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, desc, desc_dma);
	dma_free_coherent(csec_priv->dev, 19, msg, msg_dma);
	dma_free_coherent(csec_priv->dev, 1+32*2+19+32, c, c_dma);
	dma_free_coherent(csec_priv->dev, 32*2+4, hashin, hashin_dma);
	dma_free_coherent(csec_priv->dev, 32, ct, ct_dma);
	kfree(done_op);

	complete(this);
	return 0;
}

int sm2_signature_thread(void *para)
{
	struct sm2_sig_private_dma st_sig;

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);
	struct result *done_op;

	unsigned char entla[2] = {
		0x00, 0x90
	};
	unsigned char standard_ida[18] =
	{
		0x41, 0x4C, 0x49, 0x43, 0x45, 0x31, 0x32, 0x33, 0x40, 0x59, 0x41, 0x48,
		0x4F, 0x4F, 0x2E, 0x43, 0x4F, 0x4D
	};
	unsigned char standard_mes1[14] =
	{
		0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x64, 0x69, 0x67, 0x65,
		0x73, 0x74
	};
	unsigned char s_pria[32] = {
		0x12, 0x8B, 0x2F, 0xA8, 0xBD, 0x43, 0x3C, 0x6C, 0x06, 0x8C, 0x8D, 0x80, 0x3D, 0xFF, 0x79, 0x79,
		0x2A, 0x51, 0x9A, 0x55, 0x17, 0x1B, 0x1B, 0x65, 0x0C, 0x23, 0x66, 0x1D, 0x15, 0x89, 0x72, 0x63
	};
	unsigned char s_puba[64] = {
		0x0A, 0xE4, 0xC7, 0x79, 0x8A, 0xA0, 0xF1, 0x19, 0x47, 0x1B, 0xEE, 0x11, 0x82, 0x5B, 0xE4, 0x62,
		0x02, 0xBB, 0x79, 0xE2, 0xA5, 0x84, 0x44, 0x95, 0xE9, 0x7C, 0x04, 0xFF, 0x4D, 0xF2, 0x54, 0x8A,
		0x7C, 0x02, 0x40, 0xF8, 0x8F, 0x1C, 0xD4, 0xE1, 0x63, 0x52, 0xA7, 0x3C, 0x17, 0xB7, 0xF1, 0x6F,
		0x07, 0x35, 0x3E, 0x53, 0xA1, 0x76, 0xD6, 0x84, 0xA9, 0xFE, 0x0C, 0x6B, 0xB7, 0x98, 0xE8, 0x57
	};
	unsigned char rng_k[32] = {
		0x6C, 0xB2, 0x8D, 0x99, 0x38, 0x5C, 0x17, 0x5C, 0x94, 0xF9, 0x4E, 0x93, 0x48, 0x17, 0x66, 0x3F,
		0xC1, 0x76, 0xD9, 0x25, 0xDD, 0x72, 0xB7, 0x27, 0x26, 0x0D, 0xBA, 0xAE, 0x1F, 0xB2, 0xF9, 0x6F
	};
	unsigned char rs[64] = {
		0x40, 0xF1, 0xEC, 0x59, 0xF7, 0x93, 0xD9, 0xF4, 0x9E, 0x09, 0xDC, 0xEF, 0x49, 0x13, 0x0D, 0x41,
		0x94, 0xF7, 0x9F, 0xB1, 0xEE, 0xD2, 0xCA, 0xA5, 0x5B, 0xAC, 0xDB, 0x49, 0xC4, 0xE7, 0x55, 0xD1,
		0x6F, 0xC6, 0xDA, 0xC3, 0x2C, 0x5D, 0x5C, 0xF1, 0x0C, 0x77, 0xDF, 0xB2, 0x0F, 0x7C, 0x2E, 0xB6,
		0x67, 0xA4, 0x57, 0x87, 0x2F, 0xB0, 0x9E, 0xC5, 0x63, 0x27, 0xA6, 0x7E, 0xC7, 0xDE, 0xEB, 0xE7
	};

	unsigned char *fp256_param, *pri_key, *msg, *r, *s, *one, *z, *k;
	unsigned int *desc;
	dma_addr_t fp256_param_dma, desc_dma, pri_key_dma, msg_dma, r_dma, s_dma, one_dma, z_dma, k_dma;

	fp256_param = dma_alloc_coherent(csec_priv->dev, 224, &fp256_param_dma, GFP_KERNEL | GFP_DMA);
	pri_key = dma_alloc_coherent(csec_priv->dev, 32, &pri_key_dma, GFP_KERNEL | GFP_DMA);
	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, &desc_dma, GFP_KERNEL | GFP_DMA);
	msg = dma_alloc_coherent(csec_priv->dev, 14, &msg_dma, GFP_KERNEL | GFP_DMA);
	r= dma_alloc_coherent(csec_priv->dev, 32, &r_dma, GFP_KERNEL | GFP_DMA);
	s= dma_alloc_coherent(csec_priv->dev, 32, &s_dma, GFP_KERNEL | GFP_DMA);
	one= dma_alloc_coherent(csec_priv->dev, 32, &one_dma, GFP_KERNEL | GFP_DMA);
	k= dma_alloc_coherent(csec_priv->dev, 32, &k_dma, GFP_KERNEL | GFP_DMA);
	z= dma_alloc_coherent(csec_priv->dev, 2+18+6*32, &z_dma, GFP_KERNEL | GFP_DMA);

	if(!z)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	done_op = kzalloc(sizeof(struct result),GFP_KERNEL);
	if(!done_op)
	{
		csec_error(KERN_INFO "done_op kzalloc error\n");
		return -EINVAL;
	}

	memcpy(fp256_param, sm2_fp_param1, 224);
	memcpy(pri_key, s_pria, 32);
	memcpy(msg, standard_mes1, 14);
	memcpy(z, entla, 2);
	memcpy(z+2, standard_ida, 18);
	memcpy(z+2+18, sm2_fp_param1+32, 4*32);
	memcpy(z+2+18+4*32, s_puba, 64);
	memcpy(k, rng_k, 32);

	//signature
	memset(one, 0, 32);
	one[0] = 0x1;
	st_sig.ecc_dma.p = fp256_param_dma;
	st_sig.ecc_dma.a = fp256_param_dma+32;
	st_sig.ecc_dma.b = fp256_param_dma+32*2;
	st_sig.ecc_dma.gx = fp256_param_dma+32*3;
	st_sig.ecc_dma.gy = fp256_param_dma+32*4;
	st_sig.ecc_dma.n = fp256_param_dma+32*5;
	st_sig.sig_dma.r = r_dma;
	st_sig.sig_dma.s = s_dma;
	st_sig.prikey_dma = pri_key_dma;
	st_sig.z_dma = z_dma;
	st_sig.one_dma = one_dma;
	st_sig.k_dma = k_dma;
	st_sig.msg_dma = msg_dma;
	st_sig.plen = 32;
	st_sig.nlen = 32;
	st_sig.klen = 14;
	st_sig.zlen = 2+18+6*32;
	st_sig.ecc_mode = FP;
	st_sig.sig_mode = WITHID;
	st_sig.rng_mode = CONSTANT;

	do_sm2_signature(csec_priv, desc, desc_dma, &st_sig, done_op);
	if(memcmp(r, rs, 32))
		printk(KERN_INFO "sm2 signature failed!\n");
	if(memcmp(s, rs+32, 32))
		printk(KERN_INFO "sm2 signature failed!\n");

	dma_free_coherent(csec_priv->dev, 224, fp256_param, fp256_param_dma);
	dma_free_coherent(csec_priv->dev, 32, pri_key, pri_key_dma);
	dma_free_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, desc, desc_dma);
	dma_free_coherent(csec_priv->dev, 14, msg, msg_dma);
	dma_free_coherent(csec_priv->dev, 32, k, k_dma);
	dma_free_coherent(csec_priv->dev, 32, r, r_dma);
	dma_free_coherent(csec_priv->dev, 32, s, s_dma);
	dma_free_coherent(csec_priv->dev, 32, one, one_dma);
	dma_free_coherent(csec_priv->dev, 2+18+6*32, z, z_dma);

	kfree(done_op);

	complete(this);
	return 0;
}

int sm2_verify_thread(void *para)
{
	struct sm2_ver_private_dma st_ver;

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);
	struct result *done_op;

	unsigned char entla[2] = {
		0x00, 0x90
	};
	unsigned char standard_ida[18] =
	{
		0x41, 0x4C, 0x49, 0x43, 0x45, 0x31, 0x32, 0x33, 0x40, 0x59, 0x41, 0x48,
		0x4F, 0x4F, 0x2E, 0x43, 0x4F, 0x4D
	};
	unsigned char standard_mes1[14] =
	{
		0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x64, 0x69, 0x67, 0x65,
		0x73, 0x74
	};
	unsigned char s_puba[64] = {
		0x0A, 0xE4, 0xC7, 0x79, 0x8A, 0xA0, 0xF1, 0x19, 0x47, 0x1B, 0xEE, 0x11, 0x82, 0x5B, 0xE4, 0x62,
		0x02, 0xBB, 0x79, 0xE2, 0xA5, 0x84, 0x44, 0x95, 0xE9, 0x7C, 0x04, 0xFF, 0x4D, 0xF2, 0x54, 0x8A,
		0x7C, 0x02, 0x40, 0xF8, 0x8F, 0x1C, 0xD4, 0xE1, 0x63, 0x52, 0xA7, 0x3C, 0x17, 0xB7, 0xF1, 0x6F,
		0x07, 0x35, 0x3E, 0x53, 0xA1, 0x76, 0xD6, 0x84, 0xA9, 0xFE, 0x0C, 0x6B, 0xB7, 0x98, 0xE8, 0x57
	};
	unsigned char rs[64] = {
		0x40, 0xF1, 0xEC, 0x59, 0xF7, 0x93, 0xD9, 0xF4, 0x9E, 0x09, 0xDC, 0xEF, 0x49, 0x13, 0x0D, 0x41,
		0x94, 0xF7, 0x9F, 0xB1, 0xEE, 0xD2, 0xCA, 0xA5, 0x5B, 0xAC, 0xDB, 0x49, 0xC4, 0xE7, 0x55, 0xD1,
		0x6F, 0xC6, 0xDA, 0xC3, 0x2C, 0x5D, 0x5C, 0xF1, 0x0C, 0x77, 0xDF, 0xB2, 0x0F, 0x7C, 0x2E, 0xB6,
		0x67, 0xA4, 0x57, 0x87, 0x2F, 0xB0, 0x9E, 0xC5, 0x63, 0x27, 0xA6, 0x7E, 0xC7, 0xDE, 0xEB, 0xE7
	};

	unsigned char *fp256_param, *pub_key, *msg, *r, *s, *one, *z;
	unsigned int *desc;
	dma_addr_t fp256_param_dma, desc_dma, pub_key_dma, msg_dma, r_dma, s_dma, one_dma, z_dma;

	fp256_param = dma_alloc_coherent(csec_priv->dev, 224, &fp256_param_dma, GFP_KERNEL | GFP_DMA);
	pub_key = dma_alloc_coherent(csec_priv->dev, 64, &pub_key_dma, GFP_KERNEL | GFP_DMA);
	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, &desc_dma, GFP_KERNEL | GFP_DMA);
	msg = dma_alloc_coherent(csec_priv->dev, 14, &msg_dma, GFP_KERNEL | GFP_DMA);
	r= dma_alloc_coherent(csec_priv->dev, 32, &r_dma, GFP_KERNEL | GFP_DMA);
	s= dma_alloc_coherent(csec_priv->dev, 32, &s_dma, GFP_KERNEL | GFP_DMA);
	one= dma_alloc_coherent(csec_priv->dev, 32, &one_dma, GFP_KERNEL | GFP_DMA);
	z= dma_alloc_coherent(csec_priv->dev, 2+18+6*32, &z_dma, GFP_KERNEL | GFP_DMA);

	if(!z)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	done_op = kzalloc(sizeof(struct result),GFP_KERNEL);
	if(!done_op)
	{
		csec_error(KERN_INFO "done_op kzalloc error\n");
		return -EINVAL;
	}

	memcpy(fp256_param, sm2_fp_param1, 224);
	memcpy(pub_key, s_puba, 64);
	memcpy(r, rs, 32);
	memcpy(s, rs+32, 32);
	memcpy(msg, standard_mes1, 14);
	memcpy(z, entla, 2);
	memcpy(z+2, standard_ida, 18);
	memcpy(z+2+18, sm2_fp_param1+32, 4*32);
	memcpy(z+2+18+4*32, s_puba, 64);
	memset(one, 0, 32);
	one[0] = 0x1;

	//verify
	st_ver.ecc_dma.p = fp256_param_dma;
	st_ver.ecc_dma.a = fp256_param_dma+32;
	st_ver.ecc_dma.b = fp256_param_dma+32*2;
	st_ver.ecc_dma.gx = fp256_param_dma+32*3;
	st_ver.ecc_dma.gy = fp256_param_dma+32*4;
	st_ver.ecc_dma.n = fp256_param_dma+32*5;
	st_ver.pubkey_dma.x = pub_key_dma;
	st_ver.pubkey_dma.y = pub_key_dma+32;
	st_ver.sig_dma.r = r_dma;
	st_ver.sig_dma.s = s_dma;
	st_ver.z_dma = z_dma;
	st_ver.one_dma = one_dma;
	st_ver.msg_dma = msg_dma;
	st_ver.plen = 32;
	st_ver.nlen = 32;
	st_ver.klen = 14;
	st_ver.zlen = 2+18+6*32;
	st_ver.ecc_mode = FP;
	st_ver.sig_mode = WITHID;

	do_sm2_verify(csec_priv, desc, desc_dma, &st_ver, done_op);
	if(done_op->rst)
		printk(KERN_ERR "sm2 verify failed!\n");

	dma_free_coherent(csec_priv->dev, 224, fp256_param, fp256_param_dma);
	dma_free_coherent(csec_priv->dev, 64, pub_key, pub_key_dma);
	dma_free_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, desc, desc_dma);
	dma_free_coherent(csec_priv->dev, 14, msg, msg_dma);
	dma_free_coherent(csec_priv->dev, 32, r, r_dma);
	dma_free_coherent(csec_priv->dev, 32, s, s_dma);
	dma_free_coherent(csec_priv->dev, 32, one, one_dma);
	dma_free_coherent(csec_priv->dev, 2+18+6*32, z, z_dma);

	kfree(done_op);

	complete(this);
	return 0;
}

int sm2_exchange_thread(void *para)
{
	struct sm2_exc_private_dma st_exc;

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);
	struct result *done_op;

	unsigned char entla[2] = {
		0x00, 0x90
	};
	unsigned char s_ida[18] = {
		0x41, 0x4C, 0x49, 0x43, 0x45, 0x31, 0x32, 0x33, 0x40, 0x59, 0x41, 0x48, 0x4F, 0x4F, 0x2E, 0x43, 0x4F, 0x4D
	};
	unsigned char entlb[2] = {
		0x00, 0x88
	};
	unsigned char s_idb[17] = {
		0x42, 0x49, 0x4C, 0x4C, 0x34, 0x35, 0x36, 0x40, 0x59, 0x41, 0x48, 0x4F, 0x4F, 0x2E, 0x43, 0x4F, 0x4D
	};
	unsigned char s_pria[32] = {
		0x6F, 0xCB, 0xA2, 0xEF, 0x9A, 0xE0, 0xAB, 0x90, 0x2B, 0xC3, 0xBD, 0xE3, 0xFF, 0x91, 0x5D, 0x44,
		0xBA, 0x4C, 0xC7, 0x8F, 0x88, 0xE2, 0xF8, 0xE7, 0xF8, 0x99, 0x6D, 0x3B, 0x8C, 0xCE, 0xED, 0xEE
	};
	unsigned char s_puba[64] = {
		0x30, 0x99, 0x09, 0x3B, 0xF3, 0xC1, 0x37, 0xD8, 0xFC, 0xBB, 0xCD, 0xF4, 0xA2, 0xAE, 0x50, 0xF3,
		0xB0, 0xF2, 0x16, 0xC3, 0x12, 0x2D, 0x79, 0x42, 0x5F, 0xE0, 0x3A, 0x45, 0xDB, 0xFE, 0x16, 0x55,
		0x3D, 0xF7, 0x9E, 0x8D, 0xAC, 0x1C, 0xF0, 0xEC, 0xBA, 0xA2, 0xF2, 0xB4, 0x9D, 0x51, 0xA4, 0xB3,
		0x87, 0xF2, 0xEF, 0xAF, 0x48, 0x23, 0x39, 0x08, 0x6A, 0x27, 0xA8, 0xE0, 0x5B, 0xAE, 0xD9, 0x8B
	};
	unsigned char s_pubb[64] = {
		0x24, 0x54, 0x93, 0xD4, 0x46, 0xC3, 0x8D, 0x8C, 0xC0, 0xF1, 0x18, 0x37, 0x46, 0x90, 0xE7, 0xDF,
		0x63, 0x3A, 0x8A, 0x4B, 0xFB, 0x33, 0x29, 0xB5, 0xEC, 0xE6, 0x04, 0xB2, 0xB4, 0xF3, 0x7F, 0x43,
		0x53, 0xC0, 0x86, 0x9F, 0x4B, 0x9E, 0x17, 0x77, 0x3D, 0xE6, 0x8F, 0xEC, 0x45, 0xE1, 0x49, 0x04,
		0xE0, 0xDE, 0xA4, 0x5B, 0xF6, 0xCE, 0xCF, 0x99, 0x18, 0xC8, 0x5E, 0xA0, 0x47, 0xC6, 0x0A, 0x4C
	};
	unsigned char s_tpria[32] = {
		0x83, 0xA2, 0xC9, 0xC8, 0xB9, 0x6E, 0x5A, 0xF7, 0x0B, 0xD4, 0x80, 0xB4, 0x72, 0x40, 0x9A, 0x9A,
		0x32, 0x72, 0x57, 0xF1, 0xEB, 0xB7, 0x3F, 0x5B, 0x07, 0x33, 0x54, 0xB2, 0x48, 0x66, 0x85, 0x63
	};
	unsigned char s_tpuba[64] = {
		0x6C, 0xB5, 0x63, 0x38, 0x16, 0xF4, 0xDD, 0x56, 0x0B, 0x1D, 0xEC, 0x45, 0x83, 0x10, 0xCB, 0xCC,
		0x68, 0x56, 0xC0, 0x95, 0x05, 0x32, 0x4A, 0x6D, 0x23, 0x15, 0x0C, 0x40, 0x8F, 0x16, 0x2B, 0xF0,
		0x0D, 0x6F, 0xCF, 0x62, 0xF1, 0x03, 0x6C, 0x0A, 0x1B, 0x6D, 0xAC, 0xCF, 0x57, 0x39, 0x92, 0x23,
		0xA6, 0x5F, 0x7D, 0x7B, 0xF2, 0xD9, 0x63, 0x7E, 0x5B, 0xBB, 0xEB, 0x85, 0x79, 0x61, 0xBF, 0x1A
	};
	unsigned char s_tpubb[64] = {
		0x17, 0x99, 0xB2, 0xA2, 0xC7, 0x78, 0x29, 0x53, 0x00, 0xD9, 0xA2, 0x32, 0x5C, 0x68, 0x61, 0x29,
		0xB8, 0xF2, 0xB5, 0x33, 0x7B, 0x3D, 0xCF, 0x45, 0x14, 0xE8, 0xBB, 0xC1, 0x9D, 0x90, 0x0E, 0xE5,
		0x54, 0xC9, 0x28, 0x8C, 0x82, 0x73, 0x3E, 0xFD, 0xF7, 0x80, 0x8A, 0xE7, 0xF2, 0x7D, 0x0E, 0x73,
		0x2F, 0x7C, 0x73, 0xA7, 0xD9, 0xAC, 0x98, 0xB7, 0xD8, 0x74, 0x0A, 0x91, 0xD0, 0xDB, 0x3C, 0xF4
	};
	unsigned char sb[32] = {
		0x28, 0x4C, 0x8F, 0x19, 0x8F, 0x14, 0x1B, 0x50, 0x2E, 0x81, 0x25, 0x0F, 0x15, 0x81, 0xC7, 0xE9,
		0xEE, 0xB4, 0xCA, 0x69, 0x90, 0xF9, 0xE0, 0x2D, 0xF3, 0x88, 0xB4, 0x54, 0x71, 0xF5, 0xBC, 0x5C
	};
	unsigned char sa[32] = {
		0x23, 0x44, 0x4D, 0xAF, 0x8E, 0xD7, 0x53, 0x43, 0x66, 0xCB, 0x90, 0x1C, 0x84, 0xB3, 0xBD, 0xBB,
		0x63, 0x50, 0x4F, 0x40, 0x65, 0xC1, 0x11, 0x6C, 0x91, 0xA4, 0xC0, 0x06, 0x97, 0xE6, 0xCF, 0x7A
	};

	unsigned char *fp256_param, *pri_key, *hashin, *hashout, *one, *pub_key1, *tmp_pub_key, *tmp_pri_key, *tmp_pub_key1, *x1, *x2, *z1, *z2, *key, *s1, *s2, *za, *zb;
	unsigned int *desc, *ct;
	dma_addr_t fp256_param_dma, desc_dma, pri_key_dma, hashin_dma, hashout_dma, ct_dma, one_dma, pub_key1_dma, tmp_pub_key_dma, tmp_pri_key_dma, tmp_pub_key1_dma, x1_dma, x2_dma, z1_dma, z2_dma, key_dma, s1_dma, s2_dma, za_dma, zb_dma;

	fp256_param = dma_alloc_coherent(csec_priv->dev, 224, &fp256_param_dma, GFP_KERNEL | GFP_DMA);
	pri_key = dma_alloc_coherent(csec_priv->dev, 32, &pri_key_dma, GFP_KERNEL | GFP_DMA);
	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE*2, &desc_dma, GFP_KERNEL | GFP_DMA);
	hashin = dma_alloc_coherent(csec_priv->dev, 32*2+4, &hashin_dma, GFP_KERNEL | GFP_DMA);
	hashout= dma_alloc_coherent(csec_priv->dev, 128, &hashout_dma, GFP_KERNEL | GFP_DMA);
	ct= dma_alloc_coherent(csec_priv->dev, 32, &ct_dma, GFP_KERNEL | GFP_DMA);
	one= dma_alloc_coherent(csec_priv->dev, 32, &one_dma, GFP_KERNEL | GFP_DMA);
	pub_key1 = dma_alloc_coherent(csec_priv->dev, 32*2, &pub_key1_dma, GFP_KERNEL | GFP_DMA);
	tmp_pub_key = dma_alloc_coherent(csec_priv->dev, 32*2, &tmp_pub_key_dma, GFP_KERNEL | GFP_DMA);
	tmp_pri_key = dma_alloc_coherent(csec_priv->dev, 32, &tmp_pri_key_dma, GFP_KERNEL | GFP_DMA);
	tmp_pub_key1 = dma_alloc_coherent(csec_priv->dev, 32*2, &tmp_pub_key1_dma, GFP_KERNEL | GFP_DMA);
	x1 = dma_alloc_coherent(csec_priv->dev, 32, &x1_dma, GFP_KERNEL | GFP_DMA);
	x2 = dma_alloc_coherent(csec_priv->dev, 32, &x2_dma, GFP_KERNEL | GFP_DMA);
	z1 = dma_alloc_coherent(csec_priv->dev, 2+18+6*32, &z1_dma, GFP_KERNEL | GFP_DMA);
	z2 = dma_alloc_coherent(csec_priv->dev, 2+17+6*32, &z2_dma, GFP_KERNEL | GFP_DMA);
	za = dma_alloc_coherent(csec_priv->dev, 32, &za_dma, GFP_KERNEL | GFP_DMA);
	zb = dma_alloc_coherent(csec_priv->dev, 32, &zb_dma, GFP_KERNEL | GFP_DMA);
	key = dma_alloc_coherent(csec_priv->dev, 16, &key_dma, GFP_KERNEL | GFP_DMA);
	s1 = dma_alloc_coherent(csec_priv->dev, 32, &s1_dma, GFP_KERNEL | GFP_DMA);
	s2 = dma_alloc_coherent(csec_priv->dev, 32, &s2_dma, GFP_KERNEL | GFP_DMA);
	if(!s2)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	done_op = kzalloc(sizeof(struct result),GFP_KERNEL);
	if(!done_op)
	{
		csec_error(KERN_INFO "done_op kzalloc error\n");
		return -EINVAL;
	}

	memcpy(fp256_param, sm2_fp_param1, 224);
	memcpy(pri_key, s_pria, 32);
	memcpy(pub_key1, s_pubb, 64);
	memcpy(tmp_pub_key, s_tpuba, 64);
	memcpy(tmp_pri_key, s_tpria, 32);
	memcpy(tmp_pub_key1, s_tpubb, 64);
	memcpy(z1, entla, 2);
	memcpy(z1+2, s_ida, 18);
	memcpy(z1+2+18, sm2_fp_param1+32, 4*32);
	memcpy(z1+2+18+4*32, s_puba, 64);
	memcpy(z2, entlb, 2);
	memcpy(z2+2, s_idb, 17);
	memcpy(z2+2+17, sm2_fp_param1+32, 4*32);
	memcpy(z2+2+17+4*32, s_pubb, 64);

	memset(x1, 0, 16);
	memset(x2, 0, 16);
	memcpy(x1+16, tmp_pub_key+16, 16);
	memcpy(x2+16, tmp_pub_key1+16, 16);
	x1[16] |= 0x80;
	x2[16] |= 0x80;
	one[0] = 0x2;
	one[1] = 0x3;
	st_exc.ecc_dma.p = fp256_param_dma;
	st_exc.ecc_dma.a = fp256_param_dma+32;
	st_exc.ecc_dma.b = fp256_param_dma+32*2;
	st_exc.ecc_dma.gx = fp256_param_dma+32*3;
	st_exc.ecc_dma.gy = fp256_param_dma+32*4;
	st_exc.ecc_dma.n = fp256_param_dma+32*5;
	st_exc.h_dma = fp256_param_dma+32*6;
	st_exc.self_tmp_pubkey_dma.x = tmp_pub_key_dma;
	st_exc.self_tmp_pubkey_dma.y = tmp_pub_key_dma+32;
	st_exc.other_pubkey_dma.x = pub_key1_dma;
	st_exc.other_pubkey_dma.y = pub_key1_dma+32;
	st_exc.other_tmp_pubkey_dma.x = tmp_pub_key1_dma;
	st_exc.other_tmp_pubkey_dma.y = tmp_pub_key1_dma+32;
	st_exc.u_dma.x = hashin_dma;
	st_exc.u_dma.y = hashin_dma+32;
	st_exc.self_prikey_dma = pri_key_dma;
	st_exc.self_tmp_prikey_dma = tmp_pri_key_dma;
	st_exc.self_x_dma = x1_dma;
	st_exc.other_x_dma = x2_dma;
	st_exc.zain_dma = z1_dma;
	st_exc.zbin_dma = z2_dma;
	st_exc.za_dma = za_dma;
	st_exc.zb_dma = zb_dma;
	st_exc.ct_dma = ct_dma;
	st_exc.key_dma = key_dma;
	st_exc.hashout_dma = hashout_dma;
	st_exc.s1_dma = s1_dma;
	st_exc.s2_dma = s2_dma;
	st_exc.s1_head_dma = one_dma;
	st_exc.s2_head_dma = one_dma+1;
	st_exc.desc_dma = desc_dma;
	st_exc.plen = 32;
	st_exc.nlen = 32;
	st_exc.klen = 16;
	st_exc.zain_len = 2+18+6*32;
	st_exc.zbin_len = 2+17+6*32;
	st_exc.ecc_mode = FP;
	st_exc.endian_mode = LITTLE;
	st_exc.id_mode = WITHID;
	st_exc.exc_mode = A;

	do_sm2_exchange(csec_priv, desc, desc_dma, &st_exc, done_op);
	if(memcmp(s1, sb, 32))
		printk(KERN_INFO "sm2 exchange failed!\n");
	if(memcmp(s2, sa, 32))
		printk(KERN_INFO "sm2 exchange failed!\n");

	dma_free_coherent(csec_priv->dev, 224, fp256_param, fp256_param_dma);
	dma_free_coherent(csec_priv->dev, 32, pri_key, pri_key_dma);
	dma_free_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE*2, desc, desc_dma);
	dma_free_coherent(csec_priv->dev, 32*2+4, hashin, hashin_dma);
	dma_free_coherent(csec_priv->dev, 128, hashout, hashout_dma);
	dma_free_coherent(csec_priv->dev, 32, ct, ct_dma);
	dma_free_coherent(csec_priv->dev, 32, one, one_dma);
	dma_free_coherent(csec_priv->dev, 32*2, pub_key1, pub_key1_dma);
	dma_free_coherent(csec_priv->dev, 32*2, tmp_pub_key, tmp_pub_key_dma);
	dma_free_coherent(csec_priv->dev, 32, tmp_pri_key, tmp_pri_key_dma);
	dma_free_coherent(csec_priv->dev, 32*2, tmp_pub_key1, tmp_pub_key1_dma);
	dma_free_coherent(csec_priv->dev, 32, x1, x1_dma);
	dma_free_coherent(csec_priv->dev, 32, x2, x2_dma);
	dma_free_coherent(csec_priv->dev, 2+18+6*32, z1, z1_dma);
	dma_free_coherent(csec_priv->dev, 2+17+6*32, z2, z2_dma);
	dma_free_coherent(csec_priv->dev, 32, za, za_dma);  // memory leak bug
	dma_free_coherent(csec_priv->dev, 32, zb, zb_dma);  // memory leak bug
	dma_free_coherent(csec_priv->dev, 16, key, key_dma);
	dma_free_coherent(csec_priv->dev, 32, s1, s1_dma);
	dma_free_coherent(csec_priv->dev, 32, s2, s2_dma);
	kfree(done_op);

	complete(this);
	return 0;
}

int sm2_fp256_test(void *para)
{
	struct sm2_genkey_private_dma st_genkey;
	struct sm2_enc_private_dma st_enc;
	struct sm2_dec_private_dma st_dec;
	struct sm2_sig_private_dma st_sig;
	struct sm2_ver_private_dma st_ver;
	struct sm2_exc_private_dma st_exc;

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);
	struct result *done_op;
	unsigned char *fp256_param, *pub_key, *pri_key, *msg, *c, *hashin, *hashout, *r, *s, *e, *one, *pub_key1, *pri_key1, *tmp_pub_key, *tmp_pri_key, *tmp_pub_key1, *tmp_pri_key1, *x1, *x2, *z1, *z2, *key, *s1, *s2, *sa, *sb;
	unsigned int *desc, *ct;
	dma_addr_t fp256_param_dma, desc_dma, pub_key_dma, pri_key_dma, msg_dma, c_dma, hashin_dma, hashout_dma, ct_dma, r_dma, s_dma, e_dma, one_dma, pub_key1_dma, pri_key1_dma, tmp_pub_key_dma, tmp_pri_key_dma, tmp_pub_key1_dma, tmp_pri_key1_dma, x1_dma, x2_dma, z1_dma, z2_dma, key_dma, s1_dma, s2_dma, sa_dma, sb_dma;
	//int status;

	fp256_param = dma_alloc_coherent(csec_priv->dev, 224, &fp256_param_dma, GFP_KERNEL | GFP_DMA);
	pub_key = dma_alloc_coherent(csec_priv->dev, 32*2, &pub_key_dma, GFP_KERNEL | GFP_DMA);
	pri_key = dma_alloc_coherent(csec_priv->dev, 32, &pri_key_dma, GFP_KERNEL | GFP_DMA);
	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE*2, &desc_dma, GFP_KERNEL | GFP_DMA);
	msg = dma_alloc_coherent(csec_priv->dev, 128, &msg_dma, GFP_KERNEL | GFP_DMA);
	c = dma_alloc_coherent(csec_priv->dev, 1+32*2+128+32, &c_dma, GFP_KERNEL | GFP_DMA);
	hashin = dma_alloc_coherent(csec_priv->dev, 32*2+4, &hashin_dma, GFP_KERNEL | GFP_DMA);
	hashout= dma_alloc_coherent(csec_priv->dev, 128, &hashout_dma, GFP_KERNEL | GFP_DMA);
	ct= dma_alloc_coherent(csec_priv->dev, 32, &ct_dma, GFP_KERNEL | GFP_DMA);
	r= dma_alloc_coherent(csec_priv->dev, 32, &r_dma, GFP_KERNEL | GFP_DMA);
	s= dma_alloc_coherent(csec_priv->dev, 32, &s_dma, GFP_KERNEL | GFP_DMA);
	e= dma_alloc_coherent(csec_priv->dev, 32, &e_dma, GFP_KERNEL | GFP_DMA);
	one= dma_alloc_coherent(csec_priv->dev, 32, &one_dma, GFP_KERNEL | GFP_DMA);
	pub_key1 = dma_alloc_coherent(csec_priv->dev, 32*2, &pub_key1_dma, GFP_KERNEL | GFP_DMA);
	pri_key1 = dma_alloc_coherent(csec_priv->dev, 32, &pri_key1_dma, GFP_KERNEL | GFP_DMA);
	tmp_pub_key = dma_alloc_coherent(csec_priv->dev, 32*2, &tmp_pub_key_dma, GFP_KERNEL | GFP_DMA);
	tmp_pri_key = dma_alloc_coherent(csec_priv->dev, 32, &tmp_pri_key_dma, GFP_KERNEL | GFP_DMA);
	tmp_pub_key1 = dma_alloc_coherent(csec_priv->dev, 32*2, &tmp_pub_key1_dma, GFP_KERNEL | GFP_DMA);
	tmp_pri_key1 = dma_alloc_coherent(csec_priv->dev, 32, &tmp_pri_key1_dma, GFP_KERNEL | GFP_DMA);
	x1 = dma_alloc_coherent(csec_priv->dev, 32, &x1_dma, GFP_KERNEL | GFP_DMA);
	x2 = dma_alloc_coherent(csec_priv->dev, 32, &x2_dma, GFP_KERNEL | GFP_DMA);
	z1 = dma_alloc_coherent(csec_priv->dev, 32, &z1_dma, GFP_KERNEL | GFP_DMA);
	z2 = dma_alloc_coherent(csec_priv->dev, 32, &z2_dma, GFP_KERNEL | GFP_DMA);
	key = dma_alloc_coherent(csec_priv->dev, 16, &key_dma, GFP_KERNEL | GFP_DMA);
	s1 = dma_alloc_coherent(csec_priv->dev, 32, &s1_dma, GFP_KERNEL | GFP_DMA);
	s2 = dma_alloc_coherent(csec_priv->dev, 32, &s2_dma, GFP_KERNEL | GFP_DMA);
	sa = dma_alloc_coherent(csec_priv->dev, 32, &sa_dma, GFP_KERNEL | GFP_DMA);
	sb = dma_alloc_coherent(csec_priv->dev, 32, &sb_dma, GFP_KERNEL | GFP_DMA);
	if(!sb)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	done_op = kzalloc(sizeof(struct result),GFP_KERNEL);
	if(!done_op)
	{
		csec_error(KERN_INFO "done_op kzalloc error\n");
		return -EINVAL;
	}
	memcpy(fp256_param, sm2_fp_param1, 224);

	//generate key pair
	st_genkey.ecc_dma.p = fp256_param_dma;
	st_genkey.ecc_dma.a = fp256_param_dma+32;
	st_genkey.ecc_dma.b = fp256_param_dma+32*2;
	st_genkey.ecc_dma.gx = fp256_param_dma+32*3;
	st_genkey.ecc_dma.gy = fp256_param_dma+32*4;
	st_genkey.ecc_dma.n = fp256_param_dma+32*5;
	st_genkey.pubkey_dma.x = pub_key_dma;
	st_genkey.pubkey_dma.y = pub_key_dma+32;
	st_genkey.prikey_dma = pri_key_dma;
	st_genkey.plen = 32;
	st_genkey.nlen = 32;
	st_genkey.ecc_mode = FP;
	st_genkey.rng_mode = HARDWARE;

	do_sm2_genkey(csec_priv, desc, desc_dma, &st_genkey, done_op);

	//encrypt
	get_random_bytes(&st_enc.klen, 1);
	st_enc.klen = st_enc.klen % 128 + 1;
	get_random_bytes(msg, st_enc.klen);
	*ct = st_enc.ct = (st_enc.klen + 31)/32;
	st_enc.ecc_dma.p = fp256_param_dma;
	st_enc.ecc_dma.a = fp256_param_dma+32;
	st_enc.ecc_dma.b = fp256_param_dma+32*2;
	st_enc.ecc_dma.gx = fp256_param_dma+32*3;
	st_enc.ecc_dma.gy = fp256_param_dma+32*4;
	st_enc.ecc_dma.n = fp256_param_dma+32*5;
	st_enc.pubkey_dma.x = pub_key_dma;
	st_enc.pubkey_dma.y = pub_key_dma+32;
	st_enc.ciphertext_dma.c1 = c_dma;
	st_enc.ciphertext_dma.c2 = c_dma+1+2*32;
	st_enc.ciphertext_dma.c3 = c_dma+1+2*32+128;
	st_enc.msg_dma = msg_dma;
	st_enc.hashin_dma = hashin_dma;
//	st_enc.hashout_dma = hashout_dma;
	st_enc.ct_dma = ct_dma;
	st_enc.plen = 32;
	st_enc.nlen = 32;
	st_enc.ecc_mode = FP;
	st_enc.endian_mode = LITTLE;
	st_enc.rng_mode = HARDWARE;

	memset(done_op,0,sizeof(struct result));
	do_sm2_encrypt(csec_priv, desc, desc_dma, &st_enc, done_op);

	//decrypt
	st_dec.ecc_dma.p = fp256_param_dma;
	st_dec.ecc_dma.a = fp256_param_dma+32;
	st_dec.ecc_dma.b = fp256_param_dma+32*2;
	st_dec.ecc_dma.gx = fp256_param_dma+32*3;
	st_dec.ecc_dma.gy = fp256_param_dma+32*4;
	st_dec.ecc_dma.n = fp256_param_dma+32*5;
	st_dec.ciphertext_dma.c1 = c_dma;
	st_dec.ciphertext_dma.c2 = c_dma+1+2*32;
	st_dec.ciphertext_dma.c3 = c_dma+1+2*32+128;
	st_dec.prikey_dma = pri_key_dma;
	st_dec.msg_dma = msg_dma;
	st_dec.hashin_dma = hashin_dma;
//	st_dec.hashout_dma = hashout_dma;
	st_dec.ct_dma = ct_dma;
	st_dec.plen = 32;
	st_dec.nlen = 32;
	st_dec.klen = st_enc.klen;
	st_dec.ct = st_enc.ct;
	st_dec.ecc_mode = FP;
	st_dec.endian_mode = LITTLE;

	memset(done_op,0,sizeof(struct result));
	do_sm2_decrypt(csec_priv, desc, desc_dma, &st_dec, done_op);
	if(done_op->rst)
		printk(KERN_ERR "sm2 enc&dec failed!\n");

	//signature
	get_random_bytes(e, 32);
	memset(one, 0, 32);
	one[0] = 0x1;
	st_sig.ecc_dma.p = fp256_param_dma;
	st_sig.ecc_dma.a = fp256_param_dma+32;
	st_sig.ecc_dma.b = fp256_param_dma+32*2;
	st_sig.ecc_dma.gx = fp256_param_dma+32*3;
	st_sig.ecc_dma.gy = fp256_param_dma+32*4;
	st_sig.ecc_dma.n = fp256_param_dma+32*5;
	st_sig.sig_dma.r = r_dma;
	st_sig.sig_dma.s = s_dma;
	st_sig.prikey_dma = pri_key_dma;
	st_sig.e_dma = e_dma;
	st_sig.one_dma = one_dma;
	st_sig.plen = 32;
	st_sig.nlen = 32;
	st_sig.ecc_mode = FP;
	st_sig.sig_mode = NOID;
	st_sig.rng_mode = HARDWARE;

	memset(done_op,0,sizeof(struct result));
	do_sm2_signature(csec_priv, desc, desc_dma, &st_sig, done_op);

	//verify
	st_ver.ecc_dma.p = fp256_param_dma;
	st_ver.ecc_dma.a = fp256_param_dma+32;
	st_ver.ecc_dma.b = fp256_param_dma+32*2;
	st_ver.ecc_dma.gx = fp256_param_dma+32*3;
	st_ver.ecc_dma.gy = fp256_param_dma+32*4;
	st_ver.ecc_dma.n = fp256_param_dma+32*5;
	st_ver.pubkey_dma.x = pub_key_dma;
	st_ver.pubkey_dma.y = pub_key_dma+32;
	st_ver.sig_dma.r = r_dma;
	st_ver.sig_dma.s = s_dma;
	st_ver.e_dma = e_dma;
	st_ver.one_dma = one_dma;
	st_ver.plen = 32;
	st_ver.nlen = 32;
	st_ver.ecc_mode = FP;
	st_ver.sig_mode = NOID;

	memset(done_op,0,sizeof(struct result));
	do_sm2_verify(csec_priv, desc, desc_dma, &st_ver, done_op);
	if(done_op->rst)
		printk(KERN_ERR "sm2 sig&ver failed!\n");

	//exchange
	st_genkey.pubkey_dma.x = pub_key1_dma;
	st_genkey.pubkey_dma.y = pub_key1_dma+32;
	st_genkey.prikey_dma = pri_key1_dma;
	memset(done_op,0,sizeof(struct result));
	do_sm2_genkey(csec_priv, desc, desc_dma, &st_genkey, done_op);

	st_genkey.pubkey_dma.x = tmp_pub_key_dma;
	st_genkey.pubkey_dma.y = tmp_pub_key_dma+32;
	st_genkey.prikey_dma = tmp_pri_key_dma;
	memset(done_op,0,sizeof(struct result));
	do_sm2_genkey(csec_priv, desc, desc_dma, &st_genkey, done_op);

	st_genkey.pubkey_dma.x = tmp_pub_key1_dma;
	st_genkey.pubkey_dma.y = tmp_pub_key1_dma+32;
	st_genkey.prikey_dma = tmp_pri_key1_dma;
	memset(done_op,0,sizeof(struct result));
	do_sm2_genkey(csec_priv, desc, desc_dma, &st_genkey, done_op);

	memset(x1, 0, 16);
	memset(x2, 0, 16);
	memcpy(x1+16, tmp_pub_key+16, 16);
	memcpy(x2+16, tmp_pub_key1+16, 16);
	x1[16] |= 0x80;
	x2[16] |= 0x80;
	get_random_bytes(z1, 32);
	get_random_bytes(z2, 32);
	one[0] = 0x2;
	one[1] = 0x3;
	st_exc.ecc_dma.p = fp256_param_dma;
	st_exc.ecc_dma.a = fp256_param_dma+32;
	st_exc.ecc_dma.b = fp256_param_dma+32*2;
	st_exc.ecc_dma.gx = fp256_param_dma+32*3;
	st_exc.ecc_dma.gy = fp256_param_dma+32*4;
	st_exc.ecc_dma.n = fp256_param_dma+32*5;
	st_exc.h_dma = fp256_param_dma+32*6;
	st_exc.self_tmp_pubkey_dma.x = tmp_pub_key_dma;
	st_exc.self_tmp_pubkey_dma.y = tmp_pub_key_dma+32;
	st_exc.other_pubkey_dma.x = pub_key1_dma;
	st_exc.other_pubkey_dma.y = pub_key1_dma+32;
	st_exc.other_tmp_pubkey_dma.x = tmp_pub_key1_dma;
	st_exc.other_tmp_pubkey_dma.y = tmp_pub_key1_dma+32;
	st_exc.u_dma.x = hashin_dma;
	st_exc.u_dma.y = hashin_dma+32;
	st_exc.self_prikey_dma = pri_key_dma;
	st_exc.self_tmp_prikey_dma = tmp_pri_key_dma;
	st_exc.self_x_dma = x1_dma;
	st_exc.other_x_dma = x2_dma;
	st_exc.za_dma = z1_dma;
	st_exc.zb_dma = z2_dma;
	st_exc.ct_dma = ct_dma;
	st_exc.key_dma = key_dma;
	st_exc.hashout_dma = hashout_dma;
	st_exc.s1_dma = s1_dma;
	st_exc.s2_dma = sa_dma;
	st_exc.s1_head_dma = one_dma;
	st_exc.s2_head_dma = one_dma+1;
	st_exc.desc_dma = desc_dma;
	st_exc.plen = 32;
	st_exc.nlen = 32;
	st_exc.klen = 16;
	st_exc.ecc_mode = FP;
	st_exc.endian_mode = LITTLE;
	st_exc.id_mode = NOID;
	st_exc.exc_mode = A;

	memset(done_op,0,sizeof(struct result));
	do_sm2_exchange(csec_priv, desc, desc_dma, &st_exc, done_op);

	st_exc.self_tmp_pubkey_dma.x = tmp_pub_key1_dma;
	st_exc.self_tmp_pubkey_dma.y = tmp_pub_key1_dma+32;
	st_exc.other_pubkey_dma.x = pub_key_dma;
	st_exc.other_pubkey_dma.y = pub_key_dma+32;
	st_exc.other_tmp_pubkey_dma.x = tmp_pub_key_dma;
	st_exc.other_tmp_pubkey_dma.y = tmp_pub_key_dma+32;
	st_exc.self_prikey_dma = pri_key1_dma;
	st_exc.self_tmp_prikey_dma = tmp_pri_key1_dma;
	st_exc.self_x_dma = x2_dma;
	st_exc.other_x_dma = x1_dma;
	st_exc.s1_dma = sb_dma;
	st_exc.s2_dma = s2_dma;
	st_exc.exc_mode = B;

	memset(done_op,0,sizeof(struct result));
	do_sm2_exchange(csec_priv, desc, desc_dma, &st_exc, done_op);

	if(memcmp(sa, s2, 32))
		printk(KERN_ERR "sm2 exchange test failed!\n");
	if(memcmp(s1, sb, 32))
		printk(KERN_ERR "sm2 exchange test failed!\n");

	dma_free_coherent(csec_priv->dev, 224, fp256_param, fp256_param_dma);
	dma_free_coherent(csec_priv->dev, 32*2, pub_key, pub_key_dma);
	dma_free_coherent(csec_priv->dev, 32, pri_key, pri_key_dma);
	dma_free_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE*2, desc, desc_dma);
	dma_free_coherent(csec_priv->dev, 128, msg, msg_dma);
	dma_free_coherent(csec_priv->dev, 1+32*2+128+32, c, c_dma);
	dma_free_coherent(csec_priv->dev, 32*2+4, hashin, hashin_dma);
	dma_free_coherent(csec_priv->dev, 128, hashout, hashout_dma);
	dma_free_coherent(csec_priv->dev, 32, ct, ct_dma);
	dma_free_coherent(csec_priv->dev, 32, r, r_dma);
	dma_free_coherent(csec_priv->dev, 32, s, s_dma);
	dma_free_coherent(csec_priv->dev, 32, e, e_dma);
	dma_free_coherent(csec_priv->dev, 32, one, one_dma);
	dma_free_coherent(csec_priv->dev, 32*2, pub_key1, pub_key1_dma);
	dma_free_coherent(csec_priv->dev, 32, pri_key1, pri_key1_dma);
	dma_free_coherent(csec_priv->dev, 32*2, tmp_pub_key, tmp_pub_key_dma);
	dma_free_coherent(csec_priv->dev, 32, tmp_pri_key, tmp_pri_key_dma);
	dma_free_coherent(csec_priv->dev, 32*2, tmp_pub_key1, tmp_pub_key1_dma);
	dma_free_coherent(csec_priv->dev, 32, tmp_pri_key1, tmp_pri_key1_dma);
	dma_free_coherent(csec_priv->dev, 32, x1, x1_dma);
	dma_free_coherent(csec_priv->dev, 32, x2, x2_dma);
	dma_free_coherent(csec_priv->dev, 32, z1, z1_dma);
	dma_free_coherent(csec_priv->dev, 32, z2, z2_dma);
	dma_free_coherent(csec_priv->dev, 16, key, key_dma);
	dma_free_coherent(csec_priv->dev, 32, s1, s1_dma);
	dma_free_coherent(csec_priv->dev, 32, s2, s2_dma);
	dma_free_coherent(csec_priv->dev, 32, sa, sa_dma);
	dma_free_coherent(csec_priv->dev, 32, sb, sb_dma);
	kfree(done_op);

	complete(this);
	return 0;
}

void sm2_multi_test(void)
{
	int i;
	struct timeval timeinfo;
	unsigned long start_tm_s = 0;
	unsigned long start_tm_us = 0;
	unsigned long finish_tm_s = 0;
	unsigned long finish_tm_us = 0;
	struct task_struct *thread[THREADS_NUM];

	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_usec;

	for(i=0; i<THREADS_NUM; i++)
	{
		thread[i] = kthread_run(sm2_fp256_test, &(sym_comp[i]), "sym_thread");
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}

	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_usec;

	printk(KERN_ERR "sm2_fp256_test cost %ld us\n", (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);

	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_usec;

	for(i=0; i<THREADS_NUM; i++)
	{
		thread[i] = kthread_run(sm2_genkey_thread, &(sym_comp[i]), "sym_thread");
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}

	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_usec;

	//printk(KERN_ERR "sm2_genkey cost %ld us\n", (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);
	printk(KERN_ERR "sm2_genkey speed %ld times/s\n", THREADS_NUM*1000000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));

	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_usec;

	for(i=0; i<THREADS_NUM; i++)
	{
		thread[i] = kthread_run(sm2_encrypt_thread, &(sym_comp[i]), "sym_thread");
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}

	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_usec;

	//printk(KERN_ERR "sm2_encrypt cost %ld us\n", (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);
	printk(KERN_ERR "sm2_encrypt speed %ld times/s\n", THREADS_NUM*1000000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));

	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_usec;

	for(i=0; i<THREADS_NUM; i++)
	{
		thread[i] = kthread_run(sm2_decrypt_thread, &(sym_comp[i]), "sym_thread");
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}

	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_usec;

	//printk(KERN_ERR "sm2_decrypt cost %ld us\n", (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);
	printk(KERN_ERR "sm2_decrypt speed %ld times/s\n", THREADS_NUM*1000000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));

	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_usec;

	for(i=0; i<THREADS_NUM; i++)
	{
		thread[i] = kthread_run(sm2_signature_thread, &(sym_comp[i]), "sym_thread");
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}

	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_usec;

	//printk(KERN_ERR "sm2_signature cost %ld us\n", (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);
	printk(KERN_ERR "sm2_signature speed %ld times/s\n", THREADS_NUM*1000000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));

	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_usec;

	for(i=0; i<THREADS_NUM; i++)
	{
		thread[i] = kthread_run(sm2_verify_thread, &(sym_comp[i]), "sym_thread");
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}

	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_usec;

	//printk(KERN_ERR "sm2_verify cost %ld us\n", (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);
	printk(KERN_ERR "sm2_verify speed %ld times/s\n", THREADS_NUM*1000000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));

	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_usec;

	for(i=0; i<THREADS_NUM; i++)
	{
		thread[i] = kthread_run(sm2_exchange_thread, &(sym_comp[i]), "sym_thread");
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}

	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_usec;

	printk(KERN_ERR "sm2_exchange cost %ld us\n", (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);
	printk(KERN_ERR "sm2_exchange speed %ld times/s\n", THREADS_NUM*1000000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));
}

int rsa_api_simplified_keygen(struct csec_priv_t *csec_priv,
	struct rsa_api *rsa_api_simplified,
	struct rsa_para_genkey_st *rsa_para_simplified,
	struct rsa_para_genkey_dma *rsa_para_simplified_dma)
{
//	struct csec_priv_t *csec_priv;
	unsigned int *desc;
	unsigned char i;
	int status, loop;
	dma_addr_t desc_dma;
	struct rsa_api_ext *rsaapi_ext = NULL;
	struct rsa_genkey_dma para;
	unsigned int blen = (rsa_api_simplified->rsa_random_bit+7)/8;
	struct result *done_op;
	done_op = kmalloc(sizeof(struct result),GFP_KERNEL);
	if(!done_op)
	{
		printk(KERN_INFO "done_op kzalloc error\n");
		return -EINVAL;
	}

	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE*4, &desc_dma, GFP_KERNEL | GFP_DMA);
	if(!desc )
	{
		csec_error(KERN_ERR "desc alloc error\n");
		return -ENOMEM;
	}

	if(rsa_api_simplified->fixed == 1)
		memcpy((void *)rsa_para_simplified->e, (void *)fixed_E_param, 3);

	dma_sync_single_for_cpu(csec_priv->dev,desc_dma ,MAX_CSEC_DESCSIZE*4,DMA_BIDIRECTIONAL);
	memset(done_op,0,sizeof(struct result));

	rsaapi_ext = (struct rsa_api_ext *)kzalloc(sizeof(struct rsa_api_ext), GFP_KERNEL|GFP_DMA);

	rsaapi_ext->r0  = dma_alloc_coherent(csec_priv->dev, blen, &rsaapi_ext->r0_phys, GFP_KERNEL | GFP_DMA);
	rsaapi_ext->r1  = dma_alloc_coherent(csec_priv->dev, blen, &rsaapi_ext->r1_phys, GFP_KERNEL | GFP_DMA);
	rsaapi_ext->r2  = dma_alloc_coherent(csec_priv->dev, blen, &rsaapi_ext->r2_phys, GFP_KERNEL | GFP_DMA);
	rsaapi_ext->r3  = dma_alloc_coherent(csec_priv->dev, blen, &rsaapi_ext->r3_phys, GFP_KERNEL | GFP_DMA);
	rsaapi_ext->r4  = dma_alloc_coherent(csec_priv->dev, blen, &rsaapi_ext->r4_phys, GFP_KERNEL | GFP_DMA);
	rsaapi_ext->r5  = dma_alloc_coherent(csec_priv->dev, blen, &rsaapi_ext->r5_phys, GFP_KERNEL | GFP_DMA);
	rsaapi_ext->r6  = dma_alloc_coherent(csec_priv->dev, blen, &rsaapi_ext->r6_phys, GFP_KERNEL | GFP_DMA);
	rsaapi_ext->r7  = dma_alloc_coherent(csec_priv->dev, blen, &rsaapi_ext->r7_phys, GFP_KERNEL | GFP_DMA);
	rsaapi_ext->r8  = dma_alloc_coherent(csec_priv->dev, blen, &rsaapi_ext->r8_phys, GFP_KERNEL | GFP_DMA);
	rsaapi_ext->r9  = dma_alloc_coherent(csec_priv->dev, blen, &rsaapi_ext->r9_phys, GFP_KERNEL | GFP_DMA);

//	csec_error(KERN_INFO "test point 0 here\n");

	*((unsigned char *)rsaapi_ext->r1) = 0x05;

	for(i=0; i<blen/4; i++)
	{
		((unsigned int *)rsaapi_ext->r2)[i] = key1_r2[blen/4 - i -1];
	}

	if(rsa_api_simplified->fixed)		//use the fixed to be the size of e
	{

	}else{
//		cry_api->fixed = 3;				//set random_e 3 bytes
		do{
			get_random_bytes(&i, 1);
			rsa_api_simplified->fixed= i;
		}while((rsa_api_simplified->fixed <2) || (rsa_api_simplified->fixed > (blen/2 -4)));
	}

	get_random_bytes((unsigned char *)rsaapi_ext->r3, 32);					//	r3 is rng_seed
	*((unsigned char *)rsaapi_ext->r4 + blen/2 -1) = 0xC0;
	//memset((unsigned char *)rsaapi_ext->r4, 0, cry_api->rsaapi.rsa_random_bit/8);
	*((unsigned char *)rsaapi_ext->r5) = 2;
	*((unsigned char *)rsaapi_ext->r6) = 1;

	para.blen = blen;
	para.elen = rsa_api_simplified->fixed;
	para.crt = rsa_api_simplified->crt;
	para.sec_dma.p_dma = rsa_para_simplified_dma->privkey_prime;
	para.sec_dma.q_dma = rsa_para_simplified_dma->privkey_prime2;
	para.sec_dma.e_dma = rsa_para_simplified_dma->pubkey_exponent;
	para.sec_dma.n_dma = rsa_para_simplified_dma->pubkey_modulus;
	para.sec_dma.d_dma = rsa_para_simplified_dma->privkey_exponent;
	para.sec_dma.dp_dma = rsa_para_simplified_dma->privkey_primeExponent;
	para.sec_dma.dq_dma = rsa_para_simplified_dma->privkey_primeExponent2;
	para.sec_dma.qInv_dma = rsa_para_simplified_dma->privkey_coefficient;
	para.r_dma.r0_dma = rsaapi_ext->r0_phys;
	para.r_dma.r1_dma = rsaapi_ext->r1_phys;
	para.r_dma.r2_dma = rsaapi_ext->r2_phys;
	para.r_dma.r3_dma = rsaapi_ext->r3_phys;
	para.r_dma.r4_dma = rsaapi_ext->r4_phys;
	para.r_dma.r5_dma = rsaapi_ext->r5_phys;
	para.r_dma.r6_dma = rsaapi_ext->r6_phys;
	para.r_dma.r7_dma = rsaapi_ext->r7_phys;
	para.r_dma.r8_dma = rsaapi_ext->r8_phys;
	para.r_dma.r9_dma = rsaapi_ext->r9_phys;
	para.desc_dma = desc_dma;

	memset(done_op, 0, sizeof(struct result));

	inline_cnstr_jobdesc_rsa_genkey_simplified(desc, &para);

	do
	{
		status = cards_enqueue(csec_priv,  desc, desc_dma,ioctl_desc_done,done_op);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);

				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);

	csec_debug(KERN_INFO "cdev_csec_ioctl is called s0\n");

	while(atomic_read(&done_op->op_done)!=1)
	{
		if(CDEV_INVL)
		{
			wait_event_timeout(csec_priv->ccore_cards->dq_done,atomic_read(&done_op->op_done),CDEV_INVL);
		}
		//csec_debug(KERN_INFO "a\n");
	}
	csec_debug(KERN_INFO "cdev_csec_ioctl is called s1, over!\n!");

	dma_sync_single_for_cpu(csec_priv->dev, desc_dma, MAX_CSEC_DESCSIZE*4, DMA_BIDIRECTIONAL);

	if(done_op->rst!=0)
	{
		return -EINVAL;
	}

	dma_free_coherent(csec_priv->dev, blen, rsaapi_ext->r0, rsaapi_ext->r0_phys);
	dma_free_coherent(csec_priv->dev, blen, rsaapi_ext->r1, rsaapi_ext->r1_phys);
	dma_free_coherent(csec_priv->dev, blen, rsaapi_ext->r2, rsaapi_ext->r2_phys);
	dma_free_coherent(csec_priv->dev, blen, rsaapi_ext->r3, rsaapi_ext->r3_phys);
	dma_free_coherent(csec_priv->dev, blen, rsaapi_ext->r4, rsaapi_ext->r4_phys);
	dma_free_coherent(csec_priv->dev, blen, rsaapi_ext->r5, rsaapi_ext->r5_phys);
	dma_free_coherent(csec_priv->dev, blen, rsaapi_ext->r6, rsaapi_ext->r6_phys);
	dma_free_coherent(csec_priv->dev, blen, rsaapi_ext->r7, rsaapi_ext->r7_phys);
	dma_free_coherent(csec_priv->dev, blen, rsaapi_ext->r8, rsaapi_ext->r8_phys);
	dma_free_coherent(csec_priv->dev, blen, rsaapi_ext->r9, rsaapi_ext->r9_phys);

	kfree(rsaapi_ext);
	dma_free_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE*4, desc, desc_dma);
	kfree(done_op);

	return 0;
}

int  rsa_api_simplified_pub(struct csec_priv_t *csec_priv,
  struct rsa_pub_priv_st *rsa_pub_simplified,
  struct rsa_pub_priv_dma *rsa_pub_simplified_dma)
{
	unsigned int *desc;
	int status, loop;
	dma_addr_t desc_dma;
	unsigned int blen = (rsa_pub_simplified->rsa_bits+7)/8;
	struct result *done_op;
	done_op = kmalloc(sizeof(struct result),GFP_KERNEL);
	if(!done_op)
	{
		printk(KERN_INFO "done_op kzalloc error\n");
		return -EINVAL;
	}

	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, &desc_dma, GFP_KERNEL | GFP_DMA);
	if(!desc )
	{
		csec_error(KERN_ERR "desc alloc error\n");
		return -ENOMEM;
	}

	dma_sync_single_for_cpu(csec_priv->dev, desc_dma ,MAX_CSEC_DESCSIZE,DMA_BIDIRECTIONAL);
//	memset(done_op,0,sizeof(struct result));

for(loop=0; loop<LOOP_NUM; loop++){
	memset(done_op,0,sizeof(struct result));

	inline_cnstr_jobdesc_rsa_pub_priv_simplified(desc, rsa_pub_simplified_dma);

	do
	{
		status = cards_enqueue(csec_priv,  desc, desc_dma,ioctl_desc_done,done_op);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);

				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);

	csec_debug(KERN_INFO "cdev_csec_ioctl is called s0\n");

	while(atomic_read(&done_op->op_done)!=1)
	{
		if(CDEV_INVL)
		{
			wait_event_timeout(csec_priv->ccore_cards->dq_done,atomic_read(&done_op->op_done),CDEV_INVL);
		}
		//csec_debug(KERN_INFO "a\n");
	}
	csec_debug(KERN_INFO "cdev_csec_ioctl is called s1, over!\n!");

	dma_sync_single_for_cpu(csec_priv->dev,desc_dma ,MAX_CSEC_DESCSIZE,DMA_BIDIRECTIONAL);
	if(done_op->rst!=0)
	{
		return -EINVAL;
	}
}
	rsa_pub_simplified->outLen = blen;

	dma_free_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, desc, desc_dma);
	kfree(done_op);
	return 0;

}


int  rsa_api_simplified_priv(struct csec_priv_t *csec_priv,
  struct rsa_pub_priv_st *rsa_priv_simplified,
  struct rsa_pub_priv_dma *rsa_priv_simplified_dma)
{
	unsigned int *desc;
	int status, loop;
	dma_addr_t desc_dma;
	unsigned int i, blen = (rsa_priv_simplified->rsa_bits+7)/8;
	struct result *done_op;
	done_op = kmalloc(sizeof(struct result),GFP_KERNEL);
	if(!done_op)
	{
		printk(KERN_INFO "done_op kzalloc error\n");
		return -EINVAL;
	}

	desc = dma_alloc_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, &desc_dma, GFP_KERNEL | GFP_DMA);
	if(!desc )
	{
		csec_error(KERN_ERR "desc alloc error\n");
		return -ENOMEM;
	}

//	csec_priv = cards_enqueue_pre(ccore_cards);

	dma_sync_single_for_cpu(csec_priv->dev, desc_dma ,MAX_CSEC_DESCSIZE,DMA_BIDIRECTIONAL);
//	memset(done_op,0,sizeof(struct result));

for(loop=0; loop<LOOP_NUM; loop++){
	memset(done_op,0,sizeof(struct result));

	if(rsa_priv_simplified_dma->crt == 1)
		inline_cnstr_jobdesc_rsa_priv_crt_simplified(desc, rsa_priv_simplified_dma);
	else
		inline_cnstr_jobdesc_rsa_pub_priv_simplified(desc, rsa_priv_simplified_dma);

	do
	{
		status = cards_enqueue(csec_priv,  desc, desc_dma,ioctl_desc_done,done_op);
		if(status)
		{
			if(CDEV_INVL)
			{
				//wait_event_timeout(csec_priv->ccore_cards->dq_done,0,CDEV_INVL);
				set_current_state(TASK_INTERRUPTIBLE);
				schedule_timeout(CDEV_INVL);

				csec_debug2(KERN_INFO "ce0\n");
			}
		}
	}while(status==-EBUSY);

	csec_debug(KERN_INFO "cdev_csec_ioctl is called s0\n");

	while(atomic_read(&done_op->op_done)!=1)
	{
		if(CDEV_INVL)
		{
			wait_event_timeout(csec_priv->ccore_cards->dq_done,atomic_read(&done_op->op_done),CDEV_INVL);
		}
		//csec_debug(KERN_INFO "a\n");
	}
	csec_debug(KERN_INFO "cdev_csec_ioctl is called s1, over!\n!");

	dma_sync_single_for_cpu(csec_priv->dev,desc_dma ,MAX_CSEC_DESCSIZE,DMA_BIDIRECTIONAL);
	if(done_op->rst!=0)
	{
		return -EINVAL;
	}
}

	rsa_priv_simplified->outLen = blen;
	for(i=0; i<blen; i++)
	{
		if(!*(rsa_priv_simplified->out + blen -1 -i))
			rsa_priv_simplified->outLen--;
		else
			break;
	}

	dma_free_coherent(csec_priv->dev, MAX_CSEC_DESCSIZE, desc, desc_dma);
	kfree(done_op);
	return 0;
}

int rsa_api_simplified_test(unsigned int rsa_bits, unsigned char fixed, unsigned char crt)
{
	unsigned int num, blen = (rsa_bits+7)/8;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);

	struct rsa_api rsa_api_simplified;
	struct rsa_para_genkey_dma rsa_para_simplified_dma;
	struct rsa_para_genkey_st rsa_para_simplified;
	struct rsa_pub_priv_dma rsa_pub_simplified_dma, rsa_priv_simplified_dma;
	struct rsa_pub_priv_st rsa_pub_simplified, rsa_priv_simplified;

	rsa_api_simplified.rsa_random_bit = rsa_bits;
	rsa_api_simplified.fixed = fixed;
	rsa_api_simplified.crt = crt;

	csec_error(KERN_INFO "test point m here\n");

	rsa_para_simplified.p= dma_alloc_coherent(csec_priv->dev, blen, &rsa_para_simplified_dma.privkey_prime, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.q = dma_alloc_coherent(csec_priv->dev, blen, &rsa_para_simplified_dma.privkey_prime2, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.e = dma_alloc_coherent(csec_priv->dev, blen, &rsa_para_simplified_dma.pubkey_exponent, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.n = dma_alloc_coherent(csec_priv->dev, blen, &rsa_para_simplified_dma.pubkey_modulus, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.d = dma_alloc_coherent(csec_priv->dev, blen, &rsa_para_simplified_dma.privkey_exponent, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.dp = dma_alloc_coherent(csec_priv->dev, blen, &rsa_para_simplified_dma.privkey_primeExponent, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.dq = dma_alloc_coherent(csec_priv->dev, blen, &rsa_para_simplified_dma.privkey_primeExponent2, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.qInv= dma_alloc_coherent(csec_priv->dev, blen, &rsa_para_simplified_dma.privkey_coefficient, GFP_KERNEL | GFP_DMA);

	if(!rsa_para_simplified.qInv)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	if(rsa_api_simplified_keygen(csec_priv, &rsa_api_simplified, &rsa_para_simplified, &rsa_para_simplified_dma ))
		printk(KERN_ERR "rsa_keygen %d failed\n", rsa_bits);

	//pub
	memset(&rsa_pub_simplified, 0, sizeof(struct rsa_pub_priv_st));
	memset(&rsa_pub_simplified_dma, 0, sizeof(struct rsa_pub_priv_dma));		//set dp~qInv 0
	rsa_pub_simplified.out = dma_alloc_coherent(csec_priv->dev, blen, &rsa_pub_simplified_dma.out_dma, GFP_KERNEL | GFP_DMA);
	rsa_pub_simplified.in = dma_alloc_coherent(csec_priv->dev, blen, &rsa_pub_simplified_dma.in_dma, GFP_KERNEL | GFP_DMA);
	rsa_pub_simplified.e = dma_alloc_coherent(csec_priv->dev, blen, &rsa_pub_simplified_dma.e_dma, GFP_KERNEL | GFP_DMA);
	rsa_pub_simplified.n = dma_alloc_coherent(csec_priv->dev, blen, &rsa_pub_simplified_dma.n_dma, GFP_KERNEL | GFP_DMA);

	if(!rsa_pub_simplified.n)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	memset(rsa_pub_simplified.in,0,blen);
	get_random_bytes(&num, 1);
	num = num %(blen/2 -2) +2;
	get_random_bytes(rsa_pub_simplified.in, num);					//pub_in

	rsa_pub_simplified.rsa_bits = rsa_bits;
	rsa_pub_simplified.inLen = num;
	memcpy(rsa_pub_simplified.e, rsa_para_simplified.e, blen);			//pub_e
	memcpy(rsa_pub_simplified.n, rsa_para_simplified.n, blen);			//pub_n
	rsa_pub_simplified_dma.blen = rsa_bits/8;
//	rsa_pub_simplified_dma.crt = crt;									//pub don't care this value

	if(rsa_api_simplified_pub(csec_priv, &rsa_pub_simplified, &rsa_pub_simplified_dma))
		printk(KERN_ERR "rsa_pub failed\n");

	//priv
	memset(&rsa_priv_simplified, 0, sizeof(struct rsa_pub_priv_st));
	memset(&rsa_priv_simplified_dma, 0, sizeof(struct rsa_pub_priv_dma));				//set dp~qInv 0
	rsa_priv_simplified.out = dma_alloc_coherent(csec_priv->dev, blen, &rsa_priv_simplified_dma.out_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.in = dma_alloc_coherent(csec_priv->dev, blen, &rsa_priv_simplified_dma.in_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.e = dma_alloc_coherent(csec_priv->dev, blen, &rsa_priv_simplified_dma.e_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.n = dma_alloc_coherent(csec_priv->dev, blen, &rsa_priv_simplified_dma.n_dma, GFP_KERNEL | GFP_DMA);

	rsa_priv_simplified.rsa_bits = rsa_bits;
	rsa_priv_simplified.inLen = rsa_pub_simplified.outLen;
	memcpy(rsa_priv_simplified.in, rsa_pub_simplified.out, blen);			//priv_in data
	memcpy(rsa_priv_simplified.e, rsa_para_simplified.d, blen);			//priv_d data
	memcpy(rsa_priv_simplified.n, rsa_para_simplified.n, blen);			//priv_n data
	rsa_priv_simplified_dma.blen = rsa_bits/8;
	rsa_priv_simplified_dma.crt = crt;

	//for priv_crt
	if(rsa_priv_simplified_dma.crt == 1){
		rsa_priv_simplified.p = dma_alloc_coherent(csec_priv->dev, blen, &rsa_priv_simplified_dma.p_dma, GFP_KERNEL | GFP_DMA);
		rsa_priv_simplified.q = dma_alloc_coherent(csec_priv->dev, blen, &rsa_priv_simplified_dma.q_dma, GFP_KERNEL | GFP_DMA);
		rsa_priv_simplified.dp = dma_alloc_coherent(csec_priv->dev, blen, &rsa_priv_simplified_dma.dp_dma, GFP_KERNEL | GFP_DMA);
		rsa_priv_simplified.dq = dma_alloc_coherent(csec_priv->dev, blen, &rsa_priv_simplified_dma.dq_dma, GFP_KERNEL | GFP_DMA);
		rsa_priv_simplified.qInv= dma_alloc_coherent(csec_priv->dev, blen, &rsa_priv_simplified_dma.qInv_dma, GFP_KERNEL | GFP_DMA);

		memcpy(rsa_priv_simplified.p, rsa_para_simplified.p, blen);				//p data
		memcpy(rsa_priv_simplified.q, rsa_para_simplified.q, blen);				//q data
		memcpy(rsa_priv_simplified.dp, rsa_para_simplified.dp, blen);				//dp data
		memcpy(rsa_priv_simplified.dq, rsa_para_simplified.dq, blen);				//dq data
		memcpy(rsa_priv_simplified.qInv, rsa_para_simplified.qInv, blen);			//qInv data
	}

	if(rsa_api_simplified_priv(csec_priv, &rsa_priv_simplified, &rsa_priv_simplified_dma))
			printk(KERN_ERR "rsa_priv failed\n");

	if(memcmp(rsa_priv_simplified.out, rsa_pub_simplified.in, blen))
	{
		printk(KERN_ERR "rsa %d compare error\n", rsa_bits);
		while(1);
	}else
		printk(KERN_ERR "rsa %d compare succeed\n", rsa_bits);

	dma_free_coherent(csec_priv->dev, blen, rsa_para_simplified.p, rsa_para_simplified_dma.privkey_prime);
	dma_free_coherent(csec_priv->dev, blen, rsa_para_simplified.q, rsa_para_simplified_dma.privkey_prime2);
	dma_free_coherent(csec_priv->dev, blen, rsa_para_simplified.e, rsa_para_simplified_dma.pubkey_exponent);
	dma_free_coherent(csec_priv->dev, blen, rsa_para_simplified.n, rsa_para_simplified_dma.pubkey_modulus);
	dma_free_coherent(csec_priv->dev, blen, rsa_para_simplified.d, rsa_para_simplified_dma.privkey_exponent);
	dma_free_coherent(csec_priv->dev, blen, rsa_para_simplified.dp, rsa_para_simplified_dma.privkey_primeExponent);
	dma_free_coherent(csec_priv->dev, blen, rsa_para_simplified.dq, rsa_para_simplified_dma.privkey_primeExponent2);
	dma_free_coherent(csec_priv->dev, blen, rsa_para_simplified.qInv, rsa_para_simplified_dma.privkey_coefficient);

	dma_free_coherent(csec_priv->dev, blen, rsa_pub_simplified.out, rsa_pub_simplified_dma.out_dma);
	dma_free_coherent(csec_priv->dev, blen, rsa_pub_simplified.in, rsa_pub_simplified_dma.in_dma);
	dma_free_coherent(csec_priv->dev, blen, rsa_pub_simplified.e, rsa_pub_simplified_dma.e_dma);
	dma_free_coherent(csec_priv->dev, blen, rsa_pub_simplified.n, rsa_pub_simplified_dma.n_dma);

	dma_free_coherent(csec_priv->dev, blen, rsa_priv_simplified.out, rsa_priv_simplified_dma.out_dma);
	dma_free_coherent(csec_priv->dev, blen, rsa_priv_simplified.in, rsa_priv_simplified_dma.in_dma);
	dma_free_coherent(csec_priv->dev, blen, rsa_priv_simplified.e, rsa_priv_simplified_dma.e_dma);
	dma_free_coherent(csec_priv->dev, blen, rsa_priv_simplified.n, rsa_priv_simplified_dma.n_dma);

	if(crt == 1){
		dma_free_coherent(csec_priv->dev, blen, rsa_priv_simplified.p, rsa_priv_simplified_dma.p_dma);
		dma_free_coherent(csec_priv->dev, blen, rsa_priv_simplified.q, rsa_priv_simplified_dma.q_dma);
		dma_free_coherent(csec_priv->dev, blen, rsa_priv_simplified.dp, rsa_priv_simplified_dma.dp_dma);
		dma_free_coherent(csec_priv->dev, blen, rsa_priv_simplified.dq, rsa_priv_simplified_dma.dq_dma);
		dma_free_coherent(csec_priv->dev, blen, rsa_priv_simplified.qInv, rsa_priv_simplified_dma.qInv_dma);
	}
	return 0;
}

int rsa1024_genkey_thread(void *para)
{
	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);

	struct rsa_api rsa_api_simplified;
	struct rsa_para_genkey_dma rsa_para_simplified_dma;
	struct rsa_para_genkey_st rsa_para_simplified;

	rsa_api_simplified.rsa_random_bit = 1024;
	rsa_api_simplified.fixed = 1;
	rsa_api_simplified.crt = 0;

	rsa_para_simplified.p= dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.privkey_prime, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.q = dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.privkey_prime2, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.e = dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.pubkey_exponent, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.n = dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.pubkey_modulus, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.d = dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.privkey_exponent, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.dp = dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.privkey_primeExponent, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.dq = dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.privkey_primeExponent2, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.qInv= dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.privkey_coefficient, GFP_KERNEL | GFP_DMA);

	if(!rsa_para_simplified.qInv)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	if(rsa_api_simplified_keygen(csec_priv, &rsa_api_simplified, &rsa_para_simplified, &rsa_para_simplified_dma))
		printk(KERN_ERR "rsa_keygen %d failed\n", rsa_api_simplified.rsa_random_bit);

	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.p, rsa_para_simplified_dma.privkey_prime);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.q, rsa_para_simplified_dma.privkey_prime2);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.e, rsa_para_simplified_dma.pubkey_exponent);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.n, rsa_para_simplified_dma.pubkey_modulus);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.d, rsa_para_simplified_dma.privkey_exponent);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.dp, rsa_para_simplified_dma.privkey_primeExponent);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.dq, rsa_para_simplified_dma.privkey_primeExponent2);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.qInv, rsa_para_simplified_dma.privkey_coefficient);

	complete(this);
	return 0;
}

int rsa2048_genkey_thread(void *para)
{
	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);

	struct rsa_api rsa_api_simplified;
	struct rsa_para_genkey_dma rsa_para_simplified_dma;
	struct rsa_para_genkey_st rsa_para_simplified;

	rsa_api_simplified.rsa_random_bit = 2048;
	rsa_api_simplified.fixed = 1;
	rsa_api_simplified.crt = 1;

	rsa_para_simplified.p= dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.privkey_prime, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.q = dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.privkey_prime2, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.e = dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.pubkey_exponent, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.n = dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.pubkey_modulus, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.d = dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.privkey_exponent, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.dp = dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.privkey_primeExponent, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.dq = dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.privkey_primeExponent2, GFP_KERNEL | GFP_DMA);
	rsa_para_simplified.qInv= dma_alloc_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, &rsa_para_simplified_dma.privkey_coefficient, GFP_KERNEL | GFP_DMA);

	if(!rsa_para_simplified.qInv)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	if(rsa_api_simplified_keygen(csec_priv, &rsa_api_simplified, &rsa_para_simplified, &rsa_para_simplified_dma))
		printk(KERN_ERR "rsa_keygen %d failed\n", rsa_api_simplified.rsa_random_bit);

	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.p, rsa_para_simplified_dma.privkey_prime);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.q, rsa_para_simplified_dma.privkey_prime2);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.e, rsa_para_simplified_dma.pubkey_exponent);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.n, rsa_para_simplified_dma.pubkey_modulus);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.d, rsa_para_simplified_dma.privkey_exponent);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.dp, rsa_para_simplified_dma.privkey_primeExponent);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.dq, rsa_para_simplified_dma.privkey_primeExponent2);
	dma_free_coherent(csec_priv->dev, rsa_api_simplified.rsa_random_bit/8, rsa_para_simplified.qInv, rsa_para_simplified_dma.privkey_coefficient);

	complete(this);
	return 0;
}

int rsa1024_pub_thread(void *para)
{
	unsigned char data_in[60] = {
		 0x14,0xba,0x6d,0x18,0xe9,0x81,0xc8,0x66,0x4e,0x0c,0x99,0x52,0xe6,0xf9,0xab,0x91,
		 0x9d,0xd5,0x54,0x66,0x51,0x01,0x64,0x9d,0xf6,0xad,0x16,0xad,0x34,0x53,0x93,0xae,
		 0x43,0x07,0xf7,0xf3,0x50,0x38,0x07,0x15,0x37,0x31,0x4c,0x20,0x02,0x33,0xdd,0xa0,
		 0x45,0xbe,0xb0,0x12,0x93,0xb7,0x73,0xeb,0x79,0x42,0x43,0xd7
	};

	unsigned char Pub_N[128] = {
		0xc9,0x96,0xc3,0xe0,0x77,0xbe,0x22,0x72,0x84,0xca,0xf9,0x22,0x73,0x1c,0xc7,0xf7,
		0xf4,0x12,0xbb,0x4c,0xd3,0xa9,0x06,0xe7,0xad,0xe1,0x9c,0x76,0x09,0xcd,0xa6,0xea,
		0x38,0x98,0xac,0x34,0x51,0x0c,0x58,0xe1,0x14,0x16,0x63,0x26,0x32,0xab,0x1e,0x76,
		0x00,0xca,0xcd,0xb9,0xe2,0x9f,0x42,0x52,0x38,0x67,0xed,0x16,0x69,0x77,0x5d,0x76,
		0xc3,0xbf,0x35,0x36,0xbf,0x2a,0x71,0xb3,0x92,0x6e,0xd2,0xb8,0x0d,0xe5,0x08,0x8b,
		0x0b,0xa9,0x9d,0x92,0xb8,0x5a,0x16,0xae,0xcd,0xa5,0xba,0x54,0x52,0x36,0xfd,0x29,
		0x4f,0x60,0xb7,0xcc,0x5d,0x58,0xb8,0xd4,0x14,0xbb,0x63,0x13,0x42,0xff,0x25,0x0b,
		0x59,0xe3,0xbf,0x88,0xdd,0xa3,0x7d,0xf4,0x31,0xcc,0x85,0x7b,0xb5,0xaf,0x3f,0x81
	};


	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);

	struct rsa_pub_priv_dma rsa_pub_simplified_dma;
	struct rsa_pub_priv_st rsa_pub_simplified;

	memset(&rsa_pub_simplified, 0, sizeof(struct rsa_pub_priv_st));		//set dp~qInv 0
	memset(&rsa_pub_simplified_dma, 0, sizeof(struct rsa_pub_priv_dma));		//set dp~qInv 0

	rsa_pub_simplified.rsa_bits = 1024;
	rsa_pub_simplified_dma.blen = rsa_pub_simplified.rsa_bits/8;
	rsa_pub_simplified_dma.crt = 0;
	rsa_pub_simplified.inLen=  sizeof(data_in);

	rsa_pub_simplified.out = dma_alloc_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, &rsa_pub_simplified_dma.out_dma, GFP_KERNEL | GFP_DMA);
	rsa_pub_simplified.in = dma_alloc_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, &rsa_pub_simplified_dma.in_dma, GFP_KERNEL | GFP_DMA);
	rsa_pub_simplified.e = dma_alloc_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, &rsa_pub_simplified_dma.e_dma, GFP_KERNEL | GFP_DMA);
	rsa_pub_simplified.n = dma_alloc_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, &rsa_pub_simplified_dma.n_dma, GFP_KERNEL | GFP_DMA);

	if(!rsa_pub_simplified.n)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	memcpy(rsa_pub_simplified.in, data_in, rsa_pub_simplified.inLen);
	memcpy(rsa_pub_simplified.e, fixed_E_param, sizeof(fixed_E_param));			//pub_e
	memcpy(rsa_pub_simplified.n, Pub_N, sizeof(Pub_N));							//pub_n

	if(rsa_api_simplified_pub(csec_priv, &rsa_pub_simplified, &rsa_pub_simplified_dma))
		printk(KERN_ERR "rsa_pub failed\n");

	dma_free_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, rsa_pub_simplified.out, rsa_pub_simplified_dma.out_dma);
	dma_free_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, rsa_pub_simplified.in, rsa_pub_simplified_dma.in_dma);
	dma_free_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, rsa_pub_simplified.e, rsa_pub_simplified_dma.e_dma);
	dma_free_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, rsa_pub_simplified.n, rsa_pub_simplified_dma.n_dma);

	complete(this);
	return 0;
}

int rsa2048_pub_thread(void *para)
{
	unsigned char data_in[35] = {
		0xe6,0xe0,0xd2,0x9b,0x6b,0x29,0xd9,0xbb,0xb6,0x24,0x56,0xbd,0xde,0x1f,0x58,0x70,
		0x90,0xb5,0xf7,0xd3,0xeb,0x9c,0xb9,0x3d,0x00,0x88,0x4b,0xd5,0x24,0x38,0x9e,0x3f,
		0x38,0xc9,0x2d,
	};

	unsigned char Pub_N[256] = {
		0xa9,0x0a,0x50,0x90,0x81,0xf3,0x33,0x68,0x8b,0x81,0xba,0x6f,0x8f,0x7e,0x4e,0x3c,
		0x4a,0xc2,0x71,0x93,0x3a,0x2d,0xac,0xed,0xae,0xe8,0xeb,0xa1,0xea,0x45,0xe4,0xc0,
		0xd9,0xad,0xf3,0x65,0xe4,0xbe,0xdd,0xe4,0x1c,0xb6,0x88,0x58,0x78,0xa6,0xfc,0xe5,
		0xc4,0xc4,0x43,0x77,0x02,0xea,0x75,0xee,0x5e,0xfe,0x6f,0x1a,0xaa,0x27,0xef,0xc1,
		0xcc,0xd1,0xa6,0x2c,0xf1,0x69,0x9a,0x09,0x35,0xf6,0xc5,0xb7,0x6c,0xdb,0xbc,0x67,
		0x76,0x43,0xd6,0xa7,0xcf,0xab,0x74,0x61,0x92,0x60,0xff,0x4d,0x25,0x1f,0x85,0x1a,
		0x09,0x8e,0xb4,0x82,0xf1,0x00,0x11,0xb3,0x01,0xd7,0xc9,0x86,0x14,0x3d,0x02,0x69,
		0x65,0x0a,0xb1,0x26,0x67,0xd7,0x9a,0xeb,0xc9,0x7d,0xe4,0xe9,0xbd,0x4a,0x3b,0xb1,
		0x8b,0xc5,0x99,0xb8,0x0d,0xdc,0x49,0x5d,0xf6,0xd7,0x38,0xec,0x4e,0xcd,0x63,0xbe,
		0x53,0x5c,0x7b,0x1e,0x00,0xf0,0x95,0x9e,0xbd,0xf4,0x17,0x16,0x57,0xaf,0x03,0xfc,
		0xd1,0xf2,0xa8,0xf9,0x73,0x69,0x8b,0x04,0xc3,0x09,0x50,0xb0,0xd1,0x7c,0x14,0x0b,
		0x2c,0xb4,0xd3,0xbc,0x61,0x5a,0x4f,0xa0,0x5c,0x63,0x63,0x65,0x2a,0x2b,0x99,0x6c,
		0x4d,0x2b,0xf3,0xd8,0xad,0xc2,0x01,0x71,0xf4,0xca,0xc1,0x85,0x4d,0xa2,0x44,0x64,
		0x1d,0xfc,0xc2,0xd4,0x46,0x64,0xef,0x30,0x8b,0x4c,0x17,0x00,0x6d,0x97,0x46,0x3a,
		0xc9,0x11,0x78,0xab,0xad,0xa4,0x61,0x2b,0x88,0xae,0x04,0xf8,0xbd,0x02,0x1f,0xef,
		0x8d,0xc6,0x30,0x72,0xf7,0x37,0xdf,0xd6,0xe5,0x32,0xf8,0x54,0x94,0x1c,0x67,0xc6
	};

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);

	struct rsa_pub_priv_dma rsa_pub_simplified_dma;
	struct rsa_pub_priv_st rsa_pub_simplified;

	memset(&rsa_pub_simplified, 0, sizeof(struct rsa_pub_priv_st));		//set dp~qInv 0
	memset(&rsa_pub_simplified_dma, 0, sizeof(struct rsa_pub_priv_dma));		//set dp~qInv 0

	rsa_pub_simplified.rsa_bits = 2048;
	rsa_pub_simplified_dma.blen = rsa_pub_simplified.rsa_bits/8;
	rsa_pub_simplified_dma.crt = 0;
	rsa_pub_simplified.inLen=  sizeof(data_in);

	rsa_pub_simplified.out = dma_alloc_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, &rsa_pub_simplified_dma.out_dma, GFP_KERNEL | GFP_DMA);
	rsa_pub_simplified.in = dma_alloc_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, &rsa_pub_simplified_dma.in_dma, GFP_KERNEL | GFP_DMA);
	rsa_pub_simplified.e = dma_alloc_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, &rsa_pub_simplified_dma.e_dma, GFP_KERNEL | GFP_DMA);
	rsa_pub_simplified.n = dma_alloc_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, &rsa_pub_simplified_dma.n_dma, GFP_KERNEL | GFP_DMA);

	if(!rsa_pub_simplified.n)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	memcpy(rsa_pub_simplified.in, data_in, rsa_pub_simplified.inLen);
	memcpy(rsa_pub_simplified.e, fixed_E_param, sizeof(fixed_E_param));			//pub_e
	memcpy(rsa_pub_simplified.n, Pub_N, sizeof(Pub_N));							//pub_n

	if(rsa_api_simplified_pub(csec_priv, &rsa_pub_simplified, &rsa_pub_simplified_dma))
		printk(KERN_ERR "rsa_pub failed\n");

	dma_free_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, rsa_pub_simplified.out, rsa_pub_simplified_dma.out_dma);
	dma_free_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, rsa_pub_simplified.in, rsa_pub_simplified_dma.in_dma);
	dma_free_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, rsa_pub_simplified.e, rsa_pub_simplified_dma.e_dma);
	dma_free_coherent(csec_priv->dev, rsa_pub_simplified_dma.blen, rsa_pub_simplified.n, rsa_pub_simplified_dma.n_dma);

	complete(this);
	return 0;
}

int rsa1024_priv_thread(void *para)
{
	unsigned char Priv_N[128] = {
		0xc9,0x96,0xc3,0xe0,0x77,0xbe,0x22,0x72,0x84,0xca,0xf9,0x22,0x73,0x1c,0xc7,0xf7,
		0xf4,0x12,0xbb,0x4c,0xd3,0xa9,0x06,0xe7,0xad,0xe1,0x9c,0x76,0x09,0xcd,0xa6,0xea,
		0x38,0x98,0xac,0x34,0x51,0x0c,0x58,0xe1,0x14,0x16,0x63,0x26,0x32,0xab,0x1e,0x76,
		0x00,0xca,0xcd,0xb9,0xe2,0x9f,0x42,0x52,0x38,0x67,0xed,0x16,0x69,0x77,0x5d,0x76,
		0xc3,0xbf,0x35,0x36,0xbf,0x2a,0x71,0xb3,0x92,0x6e,0xd2,0xb8,0x0d,0xe5,0x08,0x8b,
		0x0b,0xa9,0x9d,0x92,0xb8,0x5a,0x16,0xae,0xcd,0xa5,0xba,0x54,0x52,0x36,0xfd,0x29,
		0x4f,0x60,0xb7,0xcc,0x5d,0x58,0xb8,0xd4,0x14,0xbb,0x63,0x13,0x42,0xff,0x25,0x0b,
		0x59,0xe3,0xbf,0x88,0xdd,0xa3,0x7d,0xf4,0x31,0xcc,0x85,0x7b,0xb5,0xaf,0x3f,0x81
	};

	unsigned char Priv_D[128] = {
		0x3d,0xb9,0xae,0x1c,0x48,0xb5,0xce,0x16,0x14,0xfc,0x64,0x25,0x89,0xd6,0xb6,0x4f,
		0x82,0x6c,0x06,0x9e,0x80,0x19,0xd5,0xe6,0x0f,0x6c,0xd8,0x65,0x4f,0x92,0x66,0x05,
		0xae,0xe6,0xc9,0xcc,0x2e,0xa6,0x4d,0x8a,0x47,0x94,0x8d,0x70,0xf8,0x0e,0xe4,0x9f,
		0xb9,0x97,0x86,0x36,0xa8,0xc8,0x3e,0xff,0x98,0x4c,0x97,0x02,0xa4,0x34,0x03,0xfd,
		0x10,0x25,0x03,0xad,0x93,0xda,0x66,0xf6,0x5f,0x30,0x77,0x57,0x92,0x19,0x6f,0xa3,
		0x8c,0x6b,0xdf,0x8e,0x63,0xfc,0x1b,0xa6,0x4a,0xe4,0xd3,0x00,0x61,0x2d,0xb2,0x55,
		0x92,0x53,0x66,0xb4,0x37,0x12,0x3c,0x22,0x10,0x27,0xeb,0xad,0xb4,0xa3,0x6d,0x00,
		0xa9,0x62,0x39,0x0d,0x48,0x86,0x56,0x35,0x8c,0xce,0x7e,0x0e,0x73,0xda,0xab,0x0a
	};

	unsigned char data_tmp[128] = {
		0xf3,0xc3,0xf1,0x9d,0x8a,0xe1,0x95,0xa3,0xc0,0x80,0x32,0x17,0x5e,0x37,0xc6,0xd7,
		0xb9,0xf3,0xd7,0x68,0x85,0x1d,0xa8,0xaa,0x4e,0xd7,0x8d,0xb7,0x9b,0x2f,0x98,0xf5,
		0x9a,0xb1,0xb4,0x2b,0x33,0x60,0x36,0x7a,0xf7,0x49,0x4a,0x69,0x15,0x72,0xdd,0x0f,
		0x7f,0x2d,0x3f,0xeb,0x23,0x2b,0xb8,0x0d,0x0c,0xfa,0x8a,0x47,0xda,0xfc,0x87,0x04,
		0xe2,0x16,0x6e,0xae,0x53,0x4c,0x9b,0x24,0x08,0x9f,0x3a,0xe6,0x1a,0x1d,0xd0,0x2d,
		0x26,0x81,0x47,0x83,0x5c,0x0a,0x74,0x4e,0xa9,0x79,0xe0,0x65,0x9f,0x3d,0x82,0xd7,
		0xf0,0x2b,0xa8,0xf3,0x25,0x43,0xa9,0xd5,0x0c,0xee,0xfd,0x50,0x0c,0xbb,0xd9,0x28,
		0xfe,0x25,0x43,0xb7,0x09,0x84,0x8b,0x39,0x18,0xc0,0xda,0x2a,0x76,0xd3,0xa0,0x3e
	};

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);

	struct rsa_pub_priv_dma rsa_priv_simplified_dma;
	struct rsa_pub_priv_st rsa_priv_simplified;

	memset(&rsa_priv_simplified, 0, sizeof(struct rsa_pub_priv_st));		//set dp~qInv 0
	memset(&rsa_priv_simplified_dma, 0, sizeof(struct rsa_pub_priv_dma));		//set dp~qInv 0

	rsa_priv_simplified.rsa_bits = 1024;
	rsa_priv_simplified_dma.blen = rsa_priv_simplified.rsa_bits/8;
	rsa_priv_simplified_dma.crt = 0;
	rsa_priv_simplified.inLen=  sizeof(data_tmp);

	rsa_priv_simplified.out = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.out_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.in = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.in_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.e = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.e_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.n = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.n_dma, GFP_KERNEL | GFP_DMA);

	if(!rsa_priv_simplified.n)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	memcpy(rsa_priv_simplified.in, data_tmp, sizeof(data_tmp));
	memcpy(rsa_priv_simplified.e, Priv_D, sizeof(Priv_D));							//priv_d
	memcpy(rsa_priv_simplified.n, Priv_N, sizeof(Priv_N));							//priv_n

	if(rsa_api_simplified_priv(csec_priv, &rsa_priv_simplified, &rsa_priv_simplified_dma))
		printk(KERN_ERR "rsa_priv failed\n");

	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.out, rsa_priv_simplified_dma.out_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.in, rsa_priv_simplified_dma.in_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.e, rsa_priv_simplified_dma.e_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.n, rsa_priv_simplified_dma.n_dma);

	complete(this);
	return 0;
}

int rsa1024_priv_crt_thread(void *para)
{
	unsigned char Priv_N[128] = {
		0xc9,0x96,0xc3,0xe0,0x77,0xbe,0x22,0x72,0x84,0xca,0xf9,0x22,0x73,0x1c,0xc7,0xf7,
		0xf4,0x12,0xbb,0x4c,0xd3,0xa9,0x06,0xe7,0xad,0xe1,0x9c,0x76,0x09,0xcd,0xa6,0xea,
		0x38,0x98,0xac,0x34,0x51,0x0c,0x58,0xe1,0x14,0x16,0x63,0x26,0x32,0xab,0x1e,0x76,
		0x00,0xca,0xcd,0xb9,0xe2,0x9f,0x42,0x52,0x38,0x67,0xed,0x16,0x69,0x77,0x5d,0x76,
		0xc3,0xbf,0x35,0x36,0xbf,0x2a,0x71,0xb3,0x92,0x6e,0xd2,0xb8,0x0d,0xe5,0x08,0x8b,
		0x0b,0xa9,0x9d,0x92,0xb8,0x5a,0x16,0xae,0xcd,0xa5,0xba,0x54,0x52,0x36,0xfd,0x29,
		0x4f,0x60,0xb7,0xcc,0x5d,0x58,0xb8,0xd4,0x14,0xbb,0x63,0x13,0x42,0xff,0x25,0x0b,
		0x59,0xe3,0xbf,0x88,0xdd,0xa3,0x7d,0xf4,0x31,0xcc,0x85,0x7b,0xb5,0xaf,0x3f,0x81
	};

/*	unsigned char Priv_D[128] = {
		0x3d,0xb9,0xae,0x1c,0x48,0xb5,0xce,0x16,0x14,0xfc,0x64,0x25,0x89,0xd6,0xb6,0x4f,
		0x82,0x6c,0x06,0x9e,0x80,0x19,0xd5,0xe6,0x0f,0x6c,0xd8,0x65,0x4f,0x92,0x66,0x05,
		0xae,0xe6,0xc9,0xcc,0x2e,0xa6,0x4d,0x8a,0x47,0x94,0x8d,0x70,0xf8,0x0e,0xe4,0x9f,
		0xb9,0x97,0x86,0x36,0xa8,0xc8,0x3e,0xff,0x98,0x4c,0x97,0x02,0xa4,0x34,0x03,0xfd,
		0x10,0x25,0x03,0xad,0x93,0xda,0x66,0xf6,0x5f,0x30,0x77,0x57,0x92,0x19,0x6f,0xa3,
		0x8c,0x6b,0xdf,0x8e,0x63,0xfc,0x1b,0xa6,0x4a,0xe4,0xd3,0x00,0x61,0x2d,0xb2,0x55,
		0x92,0x53,0x66,0xb4,0x37,0x12,0x3c,0x22,0x10,0x27,0xeb,0xad,0xb4,0xa3,0x6d,0x00,
		0xa9,0x62,0x39,0x0d,0x48,0x86,0x56,0x35,0x8c,0xce,0x7e,0x0e,0x73,0xda,0xab,0x0a
	};
*/
	unsigned char data_tmp[128] = {
		0xf3,0xc3,0xf1,0x9d,0x8a,0xe1,0x95,0xa3,0xc0,0x80,0x32,0x17,0x5e,0x37,0xc6,0xd7,
		0xb9,0xf3,0xd7,0x68,0x85,0x1d,0xa8,0xaa,0x4e,0xd7,0x8d,0xb7,0x9b,0x2f,0x98,0xf5,
		0x9a,0xb1,0xb4,0x2b,0x33,0x60,0x36,0x7a,0xf7,0x49,0x4a,0x69,0x15,0x72,0xdd,0x0f,
		0x7f,0x2d,0x3f,0xeb,0x23,0x2b,0xb8,0x0d,0x0c,0xfa,0x8a,0x47,0xda,0xfc,0x87,0x04,
		0xe2,0x16,0x6e,0xae,0x53,0x4c,0x9b,0x24,0x08,0x9f,0x3a,0xe6,0x1a,0x1d,0xd0,0x2d,
		0x26,0x81,0x47,0x83,0x5c,0x0a,0x74,0x4e,0xa9,0x79,0xe0,0x65,0x9f,0x3d,0x82,0xd7,
		0xf0,0x2b,0xa8,0xf3,0x25,0x43,0xa9,0xd5,0x0c,0xee,0xfd,0x50,0x0c,0xbb,0xd9,0x28,
		0xfe,0x25,0x43,0xb7,0x09,0x84,0x8b,0x39,0x18,0xc0,0xda,0x2a,0x76,0xd3,0xa0,0x3e
	};

	unsigned char Priv_P[64] = {
		0x77,0x2b,0x13,0xfa,0x40,0x85,0xf9,0x26,0x2c,0x11,0x6d,0xfb,0xda,0x3a,0xe7,0xfa,
		0x12,0x7b,0x7a,0x5d,0xba,0x88,0x08,0xb5,0x0c,0x89,0x6f,0x58,0x9c,0x8f,0x42,0x86,
		0x42,0x10,0xd3,0x04,0x11,0x32,0xca,0x77,0x72,0x64,0xd2,0x56,0x8e,0x1a,0x8d,0x87,
		0x36,0xd0,0x07,0x97,0xf0,0x03,0x72,0x94,0xe7,0x8a,0x6b,0x70,0xe4,0xf2,0x4e,0xd2,
	};

	unsigned char Priv_Q[64] = {
		0xbf,0x5f,0x93,0x16,0x9e,0xfc,0x36,0x86,0x77,0x0c,0xdb,0x14,0xd7,0xe7,0x73,0x68,
		0x39,0x1c,0x2f,0xdc,0x9c,0x6d,0x51,0x07,0x0c,0x42,0x34,0xd2,0xb6,0xa3,0xac,0x1e,
		0xe5,0x92,0x44,0x42,0xd6,0x1d,0x53,0x2c,0x55,0x87,0x53,0x27,0xad,0x19,0x23,0xbe,
		0xff,0x36,0x6c,0x4b,0x04,0xa7,0x55,0x52,0xa8,0x8f,0x0d,0x5f,0x5d,0x51,0x54,0x9d
	};

	unsigned char Priv_dP[64] = {
		0x03,0x39,0x03,0x0c,0x76,0xa3,0x74,0x0a,0x5f,0x3a,0xa5,0x95,0x49,0xc3,0x27,0x5e,
		0xd3,0x4f,0x6f,0x4c,0x74,0x57,0x6b,0x3b,0x6a,0x70,0x4b,0x29,0x13,0xea,0x46,0x0c,
		0x24,0xe6,0x81,0x8d,0xa0,0x6d,0x78,0x59,0x84,0x3f,0x98,0xe6,0x26,0x38,0x2e,0x1c,
		0x1d,0x9b,0x98,0x57,0x74,0x44,0x92,0xcc,0x66,0x17,0xe5,0x76,0xc7,0x7e,0x7f,0x2b
	};

	unsigned char Priv_dQ[64] = {
		0xf7,0xeb,0xf9,0x4f,0x2f,0xe7,0x7d,0x96,0x08,0x48,0x23,0xd5,0xfd,0x53,0x78,0xbe,
		0x98,0xa8,0x7a,0x61,0xa2,0x0b,0x76,0x55,0x7c,0x57,0xff,0x4e,0x5b,0x45,0xff,0xc1,
		0x9f,0x1c,0x9d,0xa8,0xd9,0x8e,0xea,0xed,0x04,0x15,0xa4,0x8e,0x80,0xa7,0x11,0xeb,
		0x04,0xb4,0x37,0x9a,0x29,0x95,0xdd,0xa9,0x4e,0xa4,0x40,0xf0,0x2c,0x3f,0x90,0x2f
	};

	unsigned char Priv_qInv[64] = {
		0x3c,0x1a,0x7c,0x6a,0x22,0x12,0x6b,0xd5,0xad,0x8c,0xe5,0x17,0x81,0xb9,0x73,0x92,
		0x93,0x6c,0x7a,0xd9,0xdc,0x6a,0xb3,0x9a,0x37,0xad,0xae,0x00,0x1d,0xd2,0x25,0x2c,
		0xe8,0x88,0x92,0xe9,0xea,0x0b,0xce,0xc0,0x0d,0x67,0x4e,0xcf,0x11,0x1d,0x81,0x62,
		0x6a,0x76,0xc0,0x4a,0x47,0x7b,0x56,0xa5,0x80,0x5e,0xb6,0x1d,0xe5,0x04,0x68,0x4f
	};

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);

	struct rsa_pub_priv_dma rsa_priv_simplified_dma;
	struct rsa_pub_priv_st rsa_priv_simplified;

	memset(&rsa_priv_simplified, 0, sizeof(struct rsa_pub_priv_st));				//set dp~qInv 0
	memset(&rsa_priv_simplified_dma, 0, sizeof(struct rsa_pub_priv_dma));

	rsa_priv_simplified.rsa_bits = 1024;
	rsa_priv_simplified_dma.blen = rsa_priv_simplified.rsa_bits/8;
	rsa_priv_simplified_dma.crt = 1;
	rsa_priv_simplified.inLen=  sizeof(data_tmp);

	rsa_priv_simplified.out = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.out_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.in = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.in_dma, GFP_KERNEL | GFP_DMA);
//	rsa_priv_simplified.e = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.e_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.n = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.n_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.p = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.p_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.q = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.q_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.dp = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.dp_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.dq = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.dq_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.qInv= dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.qInv_dma, GFP_KERNEL | GFP_DMA);

	if(!rsa_priv_simplified.qInv)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	memcpy(rsa_priv_simplified.in, data_tmp, sizeof(data_tmp));
//	memcpy(rsa_priv_simplified.e, Priv_D, sizeof(Priv_D));							//priv_d
	memcpy(rsa_priv_simplified.n, Priv_N, sizeof(Priv_N));							//priv_n
	memcpy(rsa_priv_simplified.p, Priv_P, sizeof(Priv_P));							//priv_p
	memcpy(rsa_priv_simplified.q, Priv_Q, sizeof(Priv_Q));							//priv_q
	memcpy(rsa_priv_simplified.dp, Priv_dP, sizeof(Priv_dP));							//priv_dp
	memcpy(rsa_priv_simplified.dq, Priv_dQ, sizeof(Priv_dQ));							//priv_dq
	memcpy(rsa_priv_simplified.qInv, Priv_qInv, sizeof(Priv_qInv));						//priv_qInv

	if(rsa_api_simplified_priv(csec_priv, &rsa_priv_simplified, &rsa_priv_simplified_dma))
		printk(KERN_ERR "rsa_priv failed\n");

	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.out, rsa_priv_simplified_dma.out_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.in, rsa_priv_simplified_dma.in_dma);
//	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.e, rsa_priv_simplified_dma.e_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.n, rsa_priv_simplified_dma.n_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.p, rsa_priv_simplified_dma.p_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.q, rsa_priv_simplified_dma.q_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.dp, rsa_priv_simplified_dma.dp_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.dq, rsa_priv_simplified_dma.dq_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.qInv, rsa_priv_simplified_dma.qInv_dma);

	complete(this);
	return 0;
}

int rsa2048_priv_thread(void *para)
{
	unsigned char Priv_N[256] = {
		0xa9,0x0a,0x50,0x90,0x81,0xf3,0x33,0x68,0x8b,0x81,0xba,0x6f,0x8f,0x7e,0x4e,0x3c,
		0x4a,0xc2,0x71,0x93,0x3a,0x2d,0xac,0xed,0xae,0xe8,0xeb,0xa1,0xea,0x45,0xe4,0xc0,
		0xd9,0xad,0xf3,0x65,0xe4,0xbe,0xdd,0xe4,0x1c,0xb6,0x88,0x58,0x78,0xa6,0xfc,0xe5,
		0xc4,0xc4,0x43,0x77,0x02,0xea,0x75,0xee,0x5e,0xfe,0x6f,0x1a,0xaa,0x27,0xef,0xc1,
		0xcc,0xd1,0xa6,0x2c,0xf1,0x69,0x9a,0x09,0x35,0xf6,0xc5,0xb7,0x6c,0xdb,0xbc,0x67,
		0x76,0x43,0xd6,0xa7,0xcf,0xab,0x74,0x61,0x92,0x60,0xff,0x4d,0x25,0x1f,0x85,0x1a,
		0x09,0x8e,0xb4,0x82,0xf1,0x00,0x11,0xb3,0x01,0xd7,0xc9,0x86,0x14,0x3d,0x02,0x69,
		0x65,0x0a,0xb1,0x26,0x67,0xd7,0x9a,0xeb,0xc9,0x7d,0xe4,0xe9,0xbd,0x4a,0x3b,0xb1,
		0x8b,0xc5,0x99,0xb8,0x0d,0xdc,0x49,0x5d,0xf6,0xd7,0x38,0xec,0x4e,0xcd,0x63,0xbe,
		0x53,0x5c,0x7b,0x1e,0x00,0xf0,0x95,0x9e,0xbd,0xf4,0x17,0x16,0x57,0xaf,0x03,0xfc,
		0xd1,0xf2,0xa8,0xf9,0x73,0x69,0x8b,0x04,0xc3,0x09,0x50,0xb0,0xd1,0x7c,0x14,0x0b,
		0x2c,0xb4,0xd3,0xbc,0x61,0x5a,0x4f,0xa0,0x5c,0x63,0x63,0x65,0x2a,0x2b,0x99,0x6c,
		0x4d,0x2b,0xf3,0xd8,0xad,0xc2,0x01,0x71,0xf4,0xca,0xc1,0x85,0x4d,0xa2,0x44,0x64,
		0x1d,0xfc,0xc2,0xd4,0x46,0x64,0xef,0x30,0x8b,0x4c,0x17,0x00,0x6d,0x97,0x46,0x3a,
		0xc9,0x11,0x78,0xab,0xad,0xa4,0x61,0x2b,0x88,0xae,0x04,0xf8,0xbd,0x02,0x1f,0xef,
		0x8d,0xc6,0x30,0x72,0xf7,0x37,0xdf,0xd6,0xe5,0x32,0xf8,0x54,0x94,0x1c,0x67,0xc6
	};

	unsigned char Priv_D[256] = {
		0xe1,0x02,0xe5,0x1a,0xa5,0x82,0xf2,0x43,0x85,0x0c,0x7c,0x77,0x35,0x55,0xec,0x34,
		0xdb,0x60,0x43,0xee,0xbf,0xb2,0x24,0xd8,0xa4,0x50,0x56,0x87,0x2e,0x58,0x5e,0xb5,
		0x2f,0xe1,0x86,0x57,0x25,0x4d,0x91,0xc8,0xc2,0xd5,0x4f,0xdc,0x1a,0xe2,0x99,0xf8,
		0x8c,0x21,0xd4,0xb5,0x92,0x1f,0xfd,0x35,0x99,0xdc,0x6b,0x8f,0x87,0x23,0xac,0xc4,
		0x27,0x70,0xb7,0xa4,0xe4,0xe2,0x07,0x2c,0x02,0xee,0xa5,0x6d,0x62,0xe4,0x69,0x18,
		0xd4,0x78,0xbc,0x82,0x94,0x0e,0xd7,0xff,0xbc,0x72,0xdf,0x3d,0x19,0xff,0xe8,0xed,
		0xaf,0x49,0xa4,0xe6,0x08,0x83,0xd7,0x1d,0x47,0xab,0x87,0x31,0x78,0x92,0x9e,0xed,
		0x68,0x3a,0x68,0x62,0xc7,0x6a,0xcf,0x30,0x0a,0x57,0xa7,0x23,0xa6,0x97,0x1c,0xec,
		0x48,0xc9,0xf2,0x55,0x80,0xb3,0xbc,0x1b,0x3c,0xcc,0xf0,0x73,0xaa,0x6d,0xee,0xe0,
		0x14,0xff,0xfa,0xf1,0xbf,0xbc,0x28,0x0c,0xd8,0x0d,0xc7,0x29,0xc0,0x55,0x1d,0x9a,
		0x41,0xeb,0x85,0xbf,0xe1,0xf1,0xe5,0x44,0xee,0x5e,0xa9,0x6e,0x20,0x0e,0x69,0xaa,
		0x39,0x96,0xd9,0x5f,0x5c,0xd7,0x7a,0x41,0x65,0xe3,0x00,0xf2,0xd9,0x1c,0xc8,0xaf,
		0x70,0x4c,0x3e,0xc6,0x96,0x28,0x33,0x07,0xe1,0xb4,0x68,0x7f,0xf8,0x22,0xce,0x1f,
		0x44,0x3c,0x7d,0xb5,0x17,0x9d,0x47,0x32,0x30,0x19,0x27,0x29,0x62,0xdd,0x8e,0x7b,
		0x80,0xd8,0x67,0xbf,0x72,0xc5,0x17,0xfc,0x8e,0x85,0xa0,0x0d,0x98,0x2b,0xc5,0xba,
		0x06,0xa0,0x0c,0xfe,0xbb,0xaf,0xd9,0x52,0xca,0x4a,0x1e,0x5e,0x29,0x38,0xe0,0x5f
	};

	unsigned char data_tmp[256] = {
		0xa9,0x0b,0xe0,0x82,0x8e,0x61,0x0f,0x47,0x09,0x77,0x0a,0x84,0x60,0x47,0xb2,0xbe,
		0xb3,0xfc,0x75,0x79,0x08,0x81,0xd3,0xf0,0x3e,0x47,0xc9,0x8a,0x05,0x92,0x6d,0x1c,
		0xe2,0x71,0x33,0x9b,0x01,0xc1,0xbf,0xaa,0xb6,0x60,0x8a,0x4d,0x74,0x2a,0xd0,0x07,
		0x28,0x37,0x2a,0xb9,0x47,0x50,0xf6,0x3c,0x34,0xbb,0x4a,0x26,0xb5,0xc3,0x20,0x21,
		0x67,0x13,0x26,0x46,0xcf,0x63,0x85,0xe0,0x90,0x02,0x53,0x70,0x85,0xf2,0x94,0x40,
		0xa0,0x14,0xd4,0xc4,0x67,0x28,0xa9,0x26,0x15,0xdf,0xa7,0xdd,0x19,0x06,0x95,0xb7,
		0x52,0xd9,0x0a,0x44,0xe8,0xad,0x11,0x87,0xca,0x94,0xa6,0x9a,0xf3,0x80,0xa9,0xe7,
		0xd2,0x2f,0xba,0xe1,0x60,0x64,0x37,0x49,0x8d,0x68,0xd9,0x90,0xa2,0x4c,0x01,0xb1,
		0xe9,0xcd,0xa8,0xeb,0x2d,0x56,0xea,0xdf,0x23,0x4a,0x5b,0x7c,0x6f,0xe4,0xca,0x64,
		0xd3,0x32,0x38,0x55,0x23,0x58,0x20,0x62,0x03,0x8e,0xbe,0xdb,0x38,0x96,0xaf,0x29,
		0x5b,0xcd,0x2e,0xdb,0x3a,0x90,0xc6,0x96,0x48,0x17,0x4e,0x79,0x85,0x98,0x8e,0xd1,
		0xd4,0x14,0xf0,0x33,0x83,0x29,0x8a,0xaa,0x12,0x97,0x3c,0x3e,0x0a,0x3f,0x63,0x24,
		0x61,0x1b,0x1f,0x0f,0x05,0xa4,0x2a,0x83,0x28,0xc7,0x8b,0x98,0xfe,0x30,0x76,0x41,
		0x17,0xa5,0x86,0xdc,0x7d,0x6a,0x13,0x3c,0xb9,0xb3,0xf0,0x80,0x8c,0xff,0x6a,0xd4,
		0x8d,0x2a,0x06,0xc3,0x2c,0xab,0x99,0x6e,0x5d,0x74,0x3e,0x4e,0x62,0x56,0xab,0xbd,
		0x13,0x43,0x77,0x95,0x3c,0x0c,0xbc,0xd0,0x9a,0xc7,0x59,0xf1,0xae,0x1e,0x21,0x0b
	};





	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);

	struct rsa_pub_priv_dma rsa_priv_simplified_dma;
	struct rsa_pub_priv_st rsa_priv_simplified;

	memset(&rsa_priv_simplified, 0, sizeof(struct rsa_pub_priv_st));		//set dp~qInv 0
	memset(&rsa_priv_simplified_dma, 0, sizeof(struct rsa_pub_priv_dma));		//set dp~qInv 0

	rsa_priv_simplified.rsa_bits = 2048;
	rsa_priv_simplified_dma.blen = rsa_priv_simplified.rsa_bits/8;
	rsa_priv_simplified_dma.crt = 0;
	rsa_priv_simplified.inLen=  sizeof(data_tmp);

	rsa_priv_simplified.out = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.out_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.in = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.in_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.e = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.e_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.n = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.n_dma, GFP_KERNEL | GFP_DMA);

	if(!rsa_priv_simplified.n)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	memcpy(rsa_priv_simplified.in, data_tmp, sizeof(data_tmp));
	memcpy(rsa_priv_simplified.e, Priv_D, sizeof(Priv_D));							//priv_e
	memcpy(rsa_priv_simplified.n, Priv_N, sizeof(Priv_N));							//priv_n

	if(rsa_api_simplified_priv(csec_priv, &rsa_priv_simplified, &rsa_priv_simplified_dma))
		printk(KERN_ERR "rsa_priv failed\n");

	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.out, rsa_priv_simplified_dma.out_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.in, rsa_priv_simplified_dma.in_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.e, rsa_priv_simplified_dma.e_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.n, rsa_priv_simplified_dma.n_dma);

	complete(this);
	return 0;
}

int rsa2048_priv_crt_thread(void *para)
{
	unsigned char Priv_N[256] = {
		0xa9,0x0a,0x50,0x90,0x81,0xf3,0x33,0x68,0x8b,0x81,0xba,0x6f,0x8f,0x7e,0x4e,0x3c,
		0x4a,0xc2,0x71,0x93,0x3a,0x2d,0xac,0xed,0xae,0xe8,0xeb,0xa1,0xea,0x45,0xe4,0xc0,
		0xd9,0xad,0xf3,0x65,0xe4,0xbe,0xdd,0xe4,0x1c,0xb6,0x88,0x58,0x78,0xa6,0xfc,0xe5,
		0xc4,0xc4,0x43,0x77,0x02,0xea,0x75,0xee,0x5e,0xfe,0x6f,0x1a,0xaa,0x27,0xef,0xc1,
		0xcc,0xd1,0xa6,0x2c,0xf1,0x69,0x9a,0x09,0x35,0xf6,0xc5,0xb7,0x6c,0xdb,0xbc,0x67,
		0x76,0x43,0xd6,0xa7,0xcf,0xab,0x74,0x61,0x92,0x60,0xff,0x4d,0x25,0x1f,0x85,0x1a,
		0x09,0x8e,0xb4,0x82,0xf1,0x00,0x11,0xb3,0x01,0xd7,0xc9,0x86,0x14,0x3d,0x02,0x69,
		0x65,0x0a,0xb1,0x26,0x67,0xd7,0x9a,0xeb,0xc9,0x7d,0xe4,0xe9,0xbd,0x4a,0x3b,0xb1,
		0x8b,0xc5,0x99,0xb8,0x0d,0xdc,0x49,0x5d,0xf6,0xd7,0x38,0xec,0x4e,0xcd,0x63,0xbe,
		0x53,0x5c,0x7b,0x1e,0x00,0xf0,0x95,0x9e,0xbd,0xf4,0x17,0x16,0x57,0xaf,0x03,0xfc,
		0xd1,0xf2,0xa8,0xf9,0x73,0x69,0x8b,0x04,0xc3,0x09,0x50,0xb0,0xd1,0x7c,0x14,0x0b,
		0x2c,0xb4,0xd3,0xbc,0x61,0x5a,0x4f,0xa0,0x5c,0x63,0x63,0x65,0x2a,0x2b,0x99,0x6c,
		0x4d,0x2b,0xf3,0xd8,0xad,0xc2,0x01,0x71,0xf4,0xca,0xc1,0x85,0x4d,0xa2,0x44,0x64,
		0x1d,0xfc,0xc2,0xd4,0x46,0x64,0xef,0x30,0x8b,0x4c,0x17,0x00,0x6d,0x97,0x46,0x3a,
		0xc9,0x11,0x78,0xab,0xad,0xa4,0x61,0x2b,0x88,0xae,0x04,0xf8,0xbd,0x02,0x1f,0xef,
		0x8d,0xc6,0x30,0x72,0xf7,0x37,0xdf,0xd6,0xe5,0x32,0xf8,0x54,0x94,0x1c,0x67,0xc6
	};

/*	unsigned char Priv_D[256] = {
		0xe1,0x02,0xe5,0x1a,0xa5,0x82,0xf2,0x43,0x85,0x0c,0x7c,0x77,0x35,0x55,0xec,0x34,
		0xdb,0x60,0x43,0xee,0xbf,0xb2,0x24,0xd8,0xa4,0x50,0x56,0x87,0x2e,0x58,0x5e,0xb5,
		0x2f,0xe1,0x86,0x57,0x25,0x4d,0x91,0xc8,0xc2,0xd5,0x4f,0xdc,0x1a,0xe2,0x99,0xf8,
		0x8c,0x21,0xd4,0xb5,0x92,0x1f,0xfd,0x35,0x99,0xdc,0x6b,0x8f,0x87,0x23,0xac,0xc4,
		0x27,0x70,0xb7,0xa4,0xe4,0xe2,0x07,0x2c,0x02,0xee,0xa5,0x6d,0x62,0xe4,0x69,0x18,
		0xd4,0x78,0xbc,0x82,0x94,0x0e,0xd7,0xff,0xbc,0x72,0xdf,0x3d,0x19,0xff,0xe8,0xed,
		0xaf,0x49,0xa4,0xe6,0x08,0x83,0xd7,0x1d,0x47,0xab,0x87,0x31,0x78,0x92,0x9e,0xed,
		0x68,0x3a,0x68,0x62,0xc7,0x6a,0xcf,0x30,0x0a,0x57,0xa7,0x23,0xa6,0x97,0x1c,0xec,
		0x48,0xc9,0xf2,0x55,0x80,0xb3,0xbc,0x1b,0x3c,0xcc,0xf0,0x73,0xaa,0x6d,0xee,0xe0,
		0x14,0xff,0xfa,0xf1,0xbf,0xbc,0x28,0x0c,0xd8,0x0d,0xc7,0x29,0xc0,0x55,0x1d,0x9a,
		0x41,0xeb,0x85,0xbf,0xe1,0xf1,0xe5,0x44,0xee,0x5e,0xa9,0x6e,0x20,0x0e,0x69,0xaa,
		0x39,0x96,0xd9,0x5f,0x5c,0xd7,0x7a,0x41,0x65,0xe3,0x00,0xf2,0xd9,0x1c,0xc8,0xaf,
		0x70,0x4c,0x3e,0xc6,0x96,0x28,0x33,0x07,0xe1,0xb4,0x68,0x7f,0xf8,0x22,0xce,0x1f,
		0x44,0x3c,0x7d,0xb5,0x17,0x9d,0x47,0x32,0x30,0x19,0x27,0x29,0x62,0xdd,0x8e,0x7b,
		0x80,0xd8,0x67,0xbf,0x72,0xc5,0x17,0xfc,0x8e,0x85,0xa0,0x0d,0x98,0x2b,0xc5,0xba,
		0x06,0xa0,0x0c,0xfe,0xbb,0xaf,0xd9,0x52,0xca,0x4a,0x1e,0x5e,0x29,0x38,0xe0,0x5f
	};

*/
	unsigned char data_tmp[256] = {
		0xa9,0x0b,0xe0,0x82,0x8e,0x61,0x0f,0x47,0x09,0x77,0x0a,0x84,0x60,0x47,0xb2,0xbe,
		0xb3,0xfc,0x75,0x79,0x08,0x81,0xd3,0xf0,0x3e,0x47,0xc9,0x8a,0x05,0x92,0x6d,0x1c,
		0xe2,0x71,0x33,0x9b,0x01,0xc1,0xbf,0xaa,0xb6,0x60,0x8a,0x4d,0x74,0x2a,0xd0,0x07,
		0x28,0x37,0x2a,0xb9,0x47,0x50,0xf6,0x3c,0x34,0xbb,0x4a,0x26,0xb5,0xc3,0x20,0x21,
		0x67,0x13,0x26,0x46,0xcf,0x63,0x85,0xe0,0x90,0x02,0x53,0x70,0x85,0xf2,0x94,0x40,
		0xa0,0x14,0xd4,0xc4,0x67,0x28,0xa9,0x26,0x15,0xdf,0xa7,0xdd,0x19,0x06,0x95,0xb7,
		0x52,0xd9,0x0a,0x44,0xe8,0xad,0x11,0x87,0xca,0x94,0xa6,0x9a,0xf3,0x80,0xa9,0xe7,
		0xd2,0x2f,0xba,0xe1,0x60,0x64,0x37,0x49,0x8d,0x68,0xd9,0x90,0xa2,0x4c,0x01,0xb1,
		0xe9,0xcd,0xa8,0xeb,0x2d,0x56,0xea,0xdf,0x23,0x4a,0x5b,0x7c,0x6f,0xe4,0xca,0x64,
		0xd3,0x32,0x38,0x55,0x23,0x58,0x20,0x62,0x03,0x8e,0xbe,0xdb,0x38,0x96,0xaf,0x29,
		0x5b,0xcd,0x2e,0xdb,0x3a,0x90,0xc6,0x96,0x48,0x17,0x4e,0x79,0x85,0x98,0x8e,0xd1,
		0xd4,0x14,0xf0,0x33,0x83,0x29,0x8a,0xaa,0x12,0x97,0x3c,0x3e,0x0a,0x3f,0x63,0x24,
		0x61,0x1b,0x1f,0x0f,0x05,0xa4,0x2a,0x83,0x28,0xc7,0x8b,0x98,0xfe,0x30,0x76,0x41,
		0x17,0xa5,0x86,0xdc,0x7d,0x6a,0x13,0x3c,0xb9,0xb3,0xf0,0x80,0x8c,0xff,0x6a,0xd4,
		0x8d,0x2a,0x06,0xc3,0x2c,0xab,0x99,0x6e,0x5d,0x74,0x3e,0x4e,0x62,0x56,0xab,0xbd,
		0x13,0x43,0x77,0x95,0x3c,0x0c,0xbc,0xd0,0x9a,0xc7,0x59,0xf1,0xae,0x1e,0x21,0x0b
	};

	unsigned char Priv_P[128] = {
		0x65,0x9b,0x34,0x0e,0xdb,0x5f,0xfe,0x22,0xcb,0x0c,0x2c,0x1a,0x3a,0x8e,0x6a,0x6d,
		0x6c,0x8a,0x60,0xd9,0x7e,0x31,0x70,0x22,0xa5,0x5c,0x40,0x30,0xfc,0x40,0x29,0x3c,
		0x48,0x25,0x42,0x14,0x4e,0x85,0xc7,0xf8,0xbe,0x78,0xba,0xf1,0x1d,0x98,0x68,0xea,
		0xd2,0xa4,0xd6,0x39,0xeb,0xcd,0x86,0x22,0x34,0xfe,0xd0,0xbf,0x99,0x32,0x40,0xf9,
		0x97,0xce,0xcd,0xac,0xb7,0xf6,0x7b,0x52,0x61,0x28,0xd9,0x9a,0x95,0x65,0x15,0x0b,
		0xcf,0x3d,0x5b,0x32,0xf1,0x40,0xb2,0xa5,0x9c,0xb4,0x8f,0x17,0xf1,0xa2,0x22,0x3f,
		0x50,0x7f,0xb9,0x67,0xe5,0x33,0xef,0x52,0x6f,0xc0,0xac,0x70,0x60,0x08,0x9e,0x73,
		0x58,0x27,0xb2,0x04,0x92,0x6d,0xf9,0x0f,0xf9,0xfa,0x4e,0x7f,0x02,0x97,0x7f,0xec
	};

	unsigned char Priv_Q[128] = {
		0xf5,0x57,0x08,0x8c,0xb5,0xf0,0x5d,0x19,0x94,0xc0,0xa5,0x3c,0x19,0x7d,0x68,0xab,
		0x9a,0x61,0x92,0x13,0xb6,0x32,0x9b,0x46,0x2e,0xcd,0x0a,0x22,0xcf,0xb7,0x0e,0xc5,
		0x7b,0x4a,0x30,0x0b,0x9f,0x8f,0x97,0x9b,0x08,0x87,0x6c,0x1f,0x98,0x63,0xcb,0xd7,
		0x47,0x7c,0x6d,0x17,0xf8,0xaf,0x76,0xf5,0xee,0x83,0x44,0xff,0xaa,0x20,0xd6,0x17,
		0x77,0x23,0xb8,0x64,0x79,0x17,0xcd,0xe9,0xc7,0x44,0x97,0xa3,0xcd,0x28,0x7c,0x44,
		0xcf,0x2e,0x2d,0xb8,0xac,0xde,0xdf,0xbc,0x98,0x18,0x66,0x9e,0xf3,0x02,0x33,0x81,
		0x12,0x30,0x80,0xe2,0x28,0x82,0x99,0x99,0x9c,0x6f,0xec,0x7e,0xcb,0xf6,0x41,0x67,
		0x48,0xc0,0x58,0x03,0x45,0x6d,0xc1,0x1d,0xec,0x54,0x2f,0x33,0xaf,0x55,0xc3,0xd6
	};

	unsigned char Priv_dP[128] = {
		0xe9,0xca,0xfb,0x1f,0x8c,0x07,0xe1,0xea,0xfd,0xc8,0xef,0x70,0xab,0x6e,0x5b,0xc8,
		0xa0,0x29,0xc5,0x0f,0x23,0x6b,0xde,0x2c,0x9e,0x4b,0x93,0xe9,0x00,0x22,0xa1,0xe8,
		0x7d,0xc9,0x6c,0x9c,0xb4,0x0a,0xc8,0x46,0x3b,0xe3,0x74,0x03,0xf1,0x7a,0xa0,0x74,
		0xd2,0xc8,0xb0,0x35,0xe0,0x61,0x18,0x7d,0xca,0x76,0x54,0x32,0xfb,0xef,0xf1,0x40,
		0x22,0xb2,0xd8,0x2d,0x73,0x27,0xb6,0xc9,0xb4,0xd5,0x16,0x02,0x74,0xe2,0xbe,0xb2,
		0x11,0xfb,0xba,0x27,0x2f,0xfa,0x04,0x0a,0x5b,0xc2,0xff,0x56,0xa0,0x0b,0x80,0x19,
		0x13,0x61,0x0d,0xee,0xcf,0xf4,0xa1,0xf1,0x27,0xb2,0x17,0x0a,0xc5,0xb2,0xee,0x4e,
		0xbc,0xa3,0x0a,0xc4,0x8a,0xdb,0x4f,0x09,0x2a,0x86,0x0d,0x0b,0x2c,0x67,0x3f,0xaa
	};

	unsigned char Priv_dQ[128] = {
		0xb9,0x47,0x84,0x53,0x88,0xa6,0x93,0x5f,0x00,0x26,0x9d,0x50,0x24,0xac,0x26,0xfa,
		0xc4,0xef,0x8c,0xd8,0x83,0xe3,0x53,0x9a,0xe3,0xa4,0x1d,0x75,0x4d,0x61,0x47,0x1a,
		0x23,0xf5,0xab,0x8b,0x83,0x30,0x43,0xd8,0xee,0xbf,0x69,0x3a,0xac,0xb7,0xc6,0x60,
		0xe3,0x28,0x32,0x03,0xf4,0xf5,0xf0,0x14,0x76,0x38,0xb6,0x0f,0x01,0xd6,0x07,0x0a,
		0x42,0x3e,0x30,0x7c,0xc9,0x6e,0x5f,0xc3,0x77,0x80,0x7b,0x9a,0x84,0x49,0xa6,0xc9,
		0x7e,0xe4,0x36,0x6d,0x37,0x9c,0xc0,0x03,0x15,0x6b,0x1c,0xf9,0xb5,0x29,0xa9,0x30,
		0x40,0x4f,0xe8,0x12,0x4c,0x44,0x29,0x7f,0xb5,0x83,0x4d,0xaa,0x09,0x33,0xd7,0x80,
		0xff,0xd9,0xb1,0x96,0x41,0x78,0xd0,0x4b,0x93,0xc5,0x5e,0x49,0x21,0x87,0x96,0x55
	};

	unsigned char Priv_qInv[128] = {
		0x16,0x0a,0xd4,0x0c,0x66,0x3e,0xd2,0x37,0x9e,0x7c,0x7a,0x6b,0xf5,0x18,0xbe,0x41,
		0x34,0x9b,0x31,0xc4,0x88,0xe0,0x92,0x35,0x3b,0x24,0x32,0xa4,0x28,0xb5,0x75,0xc8,
		0x04,0xcc,0x0c,0x3c,0x3a,0x7d,0x73,0xb6,0xff,0xd1,0x09,0x25,0x72,0xe0,0x44,0x24,
		0xd7,0x74,0x02,0x41,0xc8,0x33,0x0e,0x03,0x83,0x2c,0xc2,0x5d,0x17,0x7f,0x8f,0x67,
		0x26,0x94,0xf2,0x64,0x5c,0x3a,0x00,0x6f,0xf7,0xe5,0x05,0x11,0xa9,0xaf,0x3b,0x35,
		0x0c,0x65,0xff,0x81,0x62,0x4d,0x65,0x8b,0x0c,0xe3,0x6d,0x07,0x65,0xbf,0xc0,0x29,
		0x88,0x75,0xc6,0xc2,0xbb,0xfb,0xc3,0xb0,0x49,0xb8,0x39,0x42,0x25,0xd6,0x00,0xbd,
		0xad,0x28,0xe6,0x99,0xc3,0x00,0x56,0x32,0x2a,0x13,0xf7,0xdd,0xc6,0xa3,0x90,0x3c
	};

	struct completion *this = (struct completion *)para;
	struct ccore_cards_t *ccore_cards = get_ccore_cards();
	struct csec_priv_t *csec_priv = cards_enqueue_pre(ccore_cards);

	struct rsa_pub_priv_dma rsa_priv_simplified_dma;
	struct rsa_pub_priv_st rsa_priv_simplified;

	memset(&rsa_priv_simplified, 0, sizeof(struct rsa_pub_priv_st));				//set dp~qInv 0
	memset(&rsa_priv_simplified_dma, 0, sizeof(struct rsa_pub_priv_dma));

	rsa_priv_simplified.rsa_bits = 2048;
	rsa_priv_simplified_dma.blen = rsa_priv_simplified.rsa_bits/8;
	rsa_priv_simplified_dma.crt = 1;
	rsa_priv_simplified.inLen=  sizeof(data_tmp);

	rsa_priv_simplified.out = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.out_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.in = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.in_dma, GFP_KERNEL | GFP_DMA);
//	rsa_priv_simplified.e = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.e_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.n = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.n_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.p = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.p_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.q = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.q_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.dp = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.dp_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.dq = dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.dq_dma, GFP_KERNEL | GFP_DMA);
	rsa_priv_simplified.qInv= dma_alloc_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, &rsa_priv_simplified_dma.qInv_dma, GFP_KERNEL | GFP_DMA);

	if(!rsa_priv_simplified.qInv)
	{
		csec_error(KERN_INFO "dma alloc error!\n");
		return -EINVAL;
	}

	memcpy(rsa_priv_simplified.in, data_tmp, sizeof(data_tmp));
//	memcpy(rsa_priv_simplified.e, Priv_D, sizeof(Priv_D));							//priv_d
	memcpy(rsa_priv_simplified.n, Priv_N, sizeof(Priv_N));							//priv_n
	memcpy(rsa_priv_simplified.p, Priv_P, sizeof(Priv_P));							//priv_p
	memcpy(rsa_priv_simplified.q, Priv_Q, sizeof(Priv_Q));							//priv_q
	memcpy(rsa_priv_simplified.dp, Priv_dP, sizeof(Priv_dP));							//priv_dp
	memcpy(rsa_priv_simplified.dq, Priv_dQ, sizeof(Priv_dQ));							//priv_dq
	memcpy(rsa_priv_simplified.qInv, Priv_qInv, sizeof(Priv_qInv));						//priv_qInv

	if(rsa_api_simplified_priv(csec_priv, &rsa_priv_simplified, &rsa_priv_simplified_dma))
		printk(KERN_ERR "rsa_priv failed\n");

	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.out, rsa_priv_simplified_dma.out_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.in, rsa_priv_simplified_dma.in_dma);
//	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.e, rsa_priv_simplified_dma.e_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.n, rsa_priv_simplified_dma.n_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.p, rsa_priv_simplified_dma.p_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.q, rsa_priv_simplified_dma.q_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.dp, rsa_priv_simplified_dma.dp_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.dq, rsa_priv_simplified_dma.dq_dma);
	dma_free_coherent(csec_priv->dev, rsa_priv_simplified_dma.blen, rsa_priv_simplified.qInv, rsa_priv_simplified_dma.qInv_dma);

	complete(this);
	return 0;
}

void rsa_multi_test(unsigned int bits, unsigned char crt)
{
	int i;
	struct timeval timeinfo;
	unsigned long start_tm_s = 0;
	unsigned long start_tm_us = 0;
	unsigned long finish_tm_s = 0;
	unsigned long finish_tm_us = 0;
	struct task_struct *thread[THREADS_NUM];

//RSA GEN_KEY
	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_usec;

	for(i=0; i<THREADS_NUM; i++)
	{
		if(bits == 1024)
		{
			thread[i] = kthread_run(rsa1024_genkey_thread, &(sym_comp[i]), "sym_thread");
		}
		else//2048
		{
			thread[i] = kthread_run(rsa2048_genkey_thread, &(sym_comp[i]), "sym_thread");
		}
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}

	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_usec;
	printk(KERN_ERR "%d rsa_genkey speed %d tims/s\n", bits, THREADS_NUM*1000*1000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));
//	printk(KERN_ERR "%d rsa_genkey speed %ld us\n", bits, (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);

//RSA PUB
	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_usec;

	for(i=0; i<THREADS_NUM; i++)
	{
		if(bits == 1024)
		{
			thread[i] = kthread_run(rsa1024_pub_thread, &(sym_comp[i]), "sym_thread");
		}
		else//2048
		{
			thread[i] = kthread_run(rsa2048_pub_thread, &(sym_comp[i]), "sym_thread");
		}
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}

	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_usec;

	printk(KERN_ERR "%d rsa_pub speed %d tims/s\n", bits, THREADS_NUM*LOOP_NUM*1000*1000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));
//	printk(KERN_ERR "%d rsa_pub speed %ld us\n", bits, (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);

//RSA PRIV
	for (i=0; i<THREADS_NUM; i++)
	{
		init_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	start_tm_s = timeinfo.tv_sec;
	start_tm_us = timeinfo.tv_usec;

	for(i=0; i<THREADS_NUM; i++)
	{
		if(bits == 1024)
		{
			if(crt != 1)
				thread[i] = kthread_run(rsa1024_priv_thread, &(sym_comp[i]), "sym_thread");
			else
				thread[i] = kthread_run(rsa1024_priv_crt_thread, &(sym_comp[i]), "sym_thread");
		}
		else//2048
		{
			if(crt != 1)
				thread[i] = kthread_run(rsa2048_priv_thread, &(sym_comp[i]), "sym_thread");
			else
				thread[i] = kthread_run(rsa2048_priv_crt_thread, &(sym_comp[i]), "sym_thread");

		}
		if (IS_ERR(thread[i]))
		{
			printk(KERN_ERR "%s: thread %d create failed\n", __func__, i);
		}
	}

	for (i=0; i<THREADS_NUM; i++)
	{
		wait_for_completion(&(sym_comp[i]));
	}

	do_gettimeofday(&timeinfo);
	finish_tm_s = timeinfo.tv_sec;
	finish_tm_us = timeinfo.tv_usec;

	printk(KERN_ERR "%d rsa_priv speed %d tims/s\n", bits, THREADS_NUM*LOOP_NUM*1000*1000/((finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us));
//	printk(KERN_ERR "%d rsa_priv speed %ld us\n", bits, (finish_tm_s - start_tm_s)*1000000+finish_tm_us-start_tm_us);
}

void ccp903_sec_test(void)
{
//while(1){
#if TEST_ASYM_SM2
	sm2_multi_test();
#endif

#if TEST_ASYM_RSA
/*
	rsa_api_simplified_test(1024, 1, 0);
	rsa_api_simplified_test(1024, 0, 0);
	rsa_api_simplified_test(1024, 0, 1);
	rsa_api_simplified_test(1024, 1, 1);

	rsa_api_simplified_test(2048, 1, 0);
	rsa_api_simplified_test(2048, 0, 0);
	rsa_api_simplified_test(2048, 0, 1);
	rsa_api_simplified_test(2048, 1, 1);
*/
	rsa_multi_test(1024, 0);
	rsa_multi_test(1024, 1);//crt
	rsa_multi_test(2048, 0);
	rsa_multi_test(2048, 1);//crt

//	rsa_api_simplified_test(1024, 1, 1);
//	rsa_api_simplified_test(2048, 1, 1);
#endif
//}
}


int cdevdemo_init(void)
{
	dev_t devno = MKDEV(cdevdemo_major, 0);
	int ret;

	cdevdemo_devp = vzalloc(sizeof(struct cdevdemo_dev));
	if (!cdevdemo_devp) {
		printk(KERN_ERR "Not enough memory for cdevdemo device structures\n");
		ret = -ENOMEM;
		goto error0;
	}
	memset(cdevdemo_devp,0,sizeof(struct cdevdemo_dev));

	ret = register_chrdev_region(devno, 1, "cdevdemo");
	if (ret)
		goto error1;
	cdev_init(&cdevdemo_devp->cdev, &cdevdemo_fops);
	cdevdemo_devp->cdev.owner = THIS_MODULE;
	cdevdemo_devp->cdev.ops = &cdevdemo_fops;
	ret = cdev_add(&cdevdemo_devp->cdev, devno, 1);
	if(ret)
		goto error2;

	cdevdemo_class = class_create(THIS_MODULE, "cdevdemo");
	if (IS_ERR(cdevdemo_class)) {
		printk(KERN_ERR "Error creating cdevdemo class.\n");
		cdev_del(&cdevdemo_devp->cdev);
		ret = PTR_ERR(cdevdemo_class);
		goto error3;
	}
	device_create(cdevdemo_class, NULL, devno, NULL, "cdevdemo");

	printk(KERN_NOTICE "Create cdevdemo device success.\n");

	ccp903_sec_test();

	return 0;

error3:
	cdev_del(&cdevdemo_devp->cdev);
error2:
	unregister_chrdev_region(MKDEV(cdevdemo_major, 0), 1);
error1:
	vfree(cdevdemo_devp);
error0:
	return ret;
}


void cdevdemo_exit(void)
{
	device_destroy(cdevdemo_class, MKDEV(cdevdemo_major, 0));
	class_destroy(cdevdemo_class);
	cdev_del(&cdevdemo_devp->cdev);
	unregister_chrdev_region(MKDEV(cdevdemo_major, 0), 1);
	vfree(cdevdemo_devp);
}

module_init(cdevdemo_init);
module_exit(cdevdemo_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mark Gao");
MODULE_DESCRIPTION("Kernel Module");
MODULE_VERSION("v1.2");
